1、JSON对象
在学习之前,我们先来看下JSON对象。早期的JSON解析器基本上就是使用JavaScript的eval()函数。由于JSON是JavaScript语法的子集,因此eval()函数可以解析,解释并释放JavaScript对象和数组。在此,对于eval()函数的具体用法和解释,我们本次不做具体的分析。
我们本次来看下面两个JSON对象的方法:
- stringify():把javaScript对象序列化为JSON字符串
- parse():把JSON字符串解析为原生JavaScript值。
例如,我们创建了一个关于书本的信息的js对象:var book = { title:"Professional JavaScript", author:["Dave"], edition:3, year:2015 }; var jsonText = JSON.stringify(book); //把js对象序列化为了json字符串
我们在浏览器中打开console面板,会看到如下信息:console.log(jsonText);
我们在同样的,将刚才已经序列化好的json对象的变量拿过来,使用parse()方法将其在转化为js值然后,再次打开浏览器console面板,会看到如下信息:var bookCopy = JSON.parse(jsonText);//把json字符串转化为js值
至此,JSON的两个方法stringify()和parse()的基本使用已经介绍完了。下面我们来介绍下这两个方法其他的用法和理解。
2.序列化选项JSON.stringify()
实际上,JSON.stringify()除了接收要序列化的JavaScript对象外,还可以接收另外两个参数,这两个参数用于指定以不同的方式序列化JavaScript对象。
- 过滤器参数,可以是一个数组,也可以是一个函数。
- 选项参数,表示是否在JSON字符串中保留缩进。
我们 先来看过滤器参数:
2.1过滤结果
如果过滤器参数是数组,那么JSON.stringify()的结果将只包含数组中列出的属性。
我们使用前面定义的book变量,来做个例子:
var jsonText = JSON.stringify(book, ["title", "edition"]);
这里我们在序列化book对象的时候,给出了一个数组参数,其中包含两个字符串:"title"和"edition"。这两个属性与将要序列化的对象中的属性是对应的,因此在返回的结果字符串中,我们会看到只包含"title"和"edition"两个属性的信息:
另外,我们再来讨论该参数为函数的时候。
传入的函数接收两个参数,属性(键)名和属性值。其中,属性名只能是字符串,而在值非键值对结构的 值时,键名可以是空字符串。为了改变序列化对象的结果,函数返回的值就是相应的值,不过,如果函数返回了undefined,那么相应的属性会被忽略。我们来看个例子//在此我们依旧调用了前面定义的book变量
var jsonText = JSON.stringify(book, function(key, value){ switch(key){
我们来查看下浏览器console面板中打印的结果:<span style="white-space:pre"> </span>//如果键为author,就将数组连接为一个字符串 case "author": return value.join(",") <span style="white-space:pre"> </span>//如果键为year,就将其值设为5000 case "year": return 5000; <span style="white-space:pre"> </span>//如果值为edition,就通过返回undefined删除该属性 case "edition": return undefined; <span style="white-space:pre"> </span>//使用default,此时返回传入的值,即其他键值对保持默认不变 default: return value; } })
//使用了函数作为第二个参数
为了更好的观察,我们把前面没有使函数作为第二个参数的返回结果拿过来: //没有使用了函数作为第二个参数我们会发现,author的值变成了"Dave"字符串,year的值也变成了5000,editio属性则消失了。
注意:Firefox3.5 和3.6对JSON.stringify()的实现有一个bug,即在使用将函数作为第二个参数的时候。对此我们不做深入。此bug在Firefox4中已经得到解决。2.2字符串缩进
JSON.stringify()方法的第三个参数用于控制结果中的缩进和空白符。如果这个参数是一个数值,那它表示的每个级别缩进的空格数。我们接着来看例子:我们来看下在浏览器consol面板中打印的结果://再次,我们依旧使用了前面定义过的book变量,并且使用stringify()方法对其序列化,注意,此处我们没有使用过滤器,即第二个参数 var jsonText = JSON.stringify(book,null,4)//4即表示每个级别要缩进四个空格
为了更好的理解和观察,我用红色矩形区域将每行的空格给标记了出来,我们会发现,每行都缩进了4个空格,同样我们将参数4改为10,其缩进的距离会更大。我们需要注意和理解的是,最大缩进空格数为10,所有大于10的值都会自动转换为10。当然,缩进参数我们也可以使用一个字符串,这个字符串会被用作缩进字符。结果://我们将4改为"- -" var jsonText = JSON.stringify(book,null,"- -")
我们会明显的发现,空格变成了我们我们传递的 那个字符串参数。同样的,如果字符串长度超过了10,结果中将只会显示先10个字符2.3、toJSON()方法
有时候,JSON.stringify()还是不能满足对某些对象进行自定义序列化的需求。我们可以使用toJSON()方法,返回其自身的JSON数据格式。我们来看个例子://在此我们重新定义个book变量 var book = { title:"Professional JavaScript", author:["Dave"], edition:3, year:2015,
结果://使用toJSON()方法,返回该对象的title toJSON:function(){ return this.title; } } var jsonText = JSON.stringify(book);
我们会发现,该方法只返回了title;
2.解析选项JSON.parse()
JSON.parse()方法也可以接收另外一个参数,该参数是一个函数,将在每个键值对上调用。我们称之为还原函数。
如果还原函数返回undefined,则表示要从结果中删除相应的键;如果返回其他值,则将该值插入到结果中。在将日期字符串转换为Date对象时,经常要用到还原函数。我们依旧来看个例子:
//我们又一次重新定义了book变量
var book = {
title:"Professional JavaScript",
author:["Dave"],
edition:3,
year:2015,
releaseDate:new Date(2011,11,1)
}
//先将其序列化为JSON字符串
var jsonText = JSON.stringify(book);
//在对jsonText进行pase方法的转换
var bookCopy = JSON.parse(jsonText, function(key, value){
if(key == "releaseDate"){
return new Date(value);
}else{
return value;
}
})
结果:
我们会发现,返回的releaseDate是一个Date对象,当我们不使用还原函数,再来看下返回的结果:
我们会发现,返回的releaseDate的值是一个字符串。
我们知道,字符串是无法调用Date对象的getFullYear()等方法的,而只有我们使用了还原函数,使其变成了Date对象后,我们就可以使用Date对象的getFullYear()等方法了。