语法
简单值
JavaScript 字符串与 JSON 字符串的最大区别在于,JSON 字符串必须使用双引号(单引号会导致语法错误)。
对象
JSON 中的对象与 JavaScript 字面量稍微有一些不同。下面是一个 JavaScript 中的对象字面量:
var person = {
name: "Nicholas",age: 29
};
JSON 表示上述对象的方式如下:
{
"name": "Nicholas","age": 29
}
与 JavaScript 的对象字面量相比,JSON 对象有两个地方不一样。首先,没有声明变量(JSON 中没有变量的概念)。其次,没有末尾的分号(因为这不是 JavaScript 语句,所以不需要分号)。
可以像下面这样在对象中嵌入对象:
{
"name": "Nicholas","age": 29,"school": {
"name": "Merrimack College","location": "North Andover,MA"
}
数组
JavaScript 中的数组字面量:
var values = [25,"hi",true];
在 JSON 中,可以采用同样的语法表示同一个数组:
[25,true]
数组和对象的结合:
[{
"title": "Professional JavaScript","authors": ["Nicholas C. Zakas"],"edition": 3,"year": 2011
},{
"title": "Professional JavaScript","authors": [
"Nicholas C. Zakas"
],"edition": 2,"year": 2009
},{
"title": "Professional Ajax","authors": [
"Nicholas C. Zakas","Jeremy McPeak","Joe Fawcett"
],"year": 2008
},"edition": 1,"year": 2007
},"year": 2006
}
]
解析与序列化
可以把JSON 数据结构解析为有用的 JavaScript 对象。
ECMAScript 5 对解析 JSON 的行为进行规范,定义了全局对象 JSON 。
JSON 对象有两个方法: stringify() 和 parse() 。在最简单的情况下,这两个方法分别用于把JavaScript 对象序列化为 JSON 字符串和把 JSON 字符串解析为原生 JavaScript 值。
var book = {
title: "Professional JavaScript",authors: [
"Nicholas C. Zakas"
],edition: 3,year: 2011
};
var jsonText = JSON.stringify(book);
保存在 jsonText 中的字符串如下所示:
{"title":"Professional JavaScript","authors":["Nicholas C. Zakas"],"edition":3,"year":2011}
将 JSON 字符串直接传递给 JSON.parse() 就可以得到相应的 JavaScript 值。例如,使用下列代码就可以创建与 book 类似的对象:
var bookCopy = JSON.parse(jsonText);
序列化选项
JSON.stringify() 除了要序列化的 JavaScript 对象外,还可以接收另外两个参数,这两个参数用于指定以不同的方式序列化 JavaScript 对象。第一个参数是个过滤器,可以是一个数组,也可以是一个函数;第二个参数是一个选项,表示是否在 JSON 字符串中保留缩进。
过滤结果
如果过滤器参数是数组,那么 JSON.stringify() 的结果中将只包含数组中列出的属性。来看下面的例子。
var jsonText = JSON.stringify(book,["title","edition"]);
如果第二个参数是函数,行为会稍有不同。传入的函数接收两个参数,属性(键)名和属性值。根据属性(键)名可以知道应该如何处理要序列化的对象中的属性。属性名只能是字符串,而在值并非键值对儿结构的值时,键名可以是空字符串。
var book = {
'title': 'Professional JavaScript','authors': [
'Nicholas C. Zakas'
],year: 2011
}
var jsonText = JSON.stringify(book,function (key,value) {
switch (key) {
case 'authors':
return value.join(',')
case 'year':
return 5000
case 'edition':
return undefined
default:
return value
}
})
字符串缩进
JSON.stringify() 方法的第三个参数用于控制结果中的缩进和空白符。如果这个参数是一个数值,那它表示的是每个级别缩进的空格数。
var jsonText = JSON.stringify(book,null,4);
toJSON() 方法
可以给对象定义 toJSON() 方法,返回其自身的 JSON 数据格式。
原生 Date 对象有一个 toJSON() 方法,能够将 JavaScript 的 Date 对象自动转换成 ISO 8601 日期字符串 。
解析选项
var book = {
"title": "Professional JavaScript","authors": [
"Nicholas C. Zakas"
],year: 2011,releaseDate: new Date(2011,11,1)
};
var jsonText = JSON.stringify(book);
var bookCopy = JSON.parse(jsonText,value) {
if (key == "releaseDate") {
return new Date(value);
} else {
return value;
}
});
alert(bookCopy.releaseDate.getFullYear());
以上代码先是为 book 对象新增了一个 releaseDate 属性,该属性保存着一个 Date 对象。这个对象在经过序列化之后变成了有效的 JSON 字符串,然后经过解析又在 bookCopy 中还原为一个 Date对象。还原函数在遇到 "releaseDate" 键时,会基于相应的值创建一个新的 Date 对象。结果就是bookCopy.releaseDate 属性中会保存一个 Date 对象。正因为如此,才能基于这个对象调用getFullYear() 方法。