《JavaScript高级程序设计》第二十章,JSON。
省略了18章(JavaScript与XML)和19章(E4X),这两章都是关于XML,API还挺多的,不过感觉现在很多都换成了JSON,就先跳过XML了。
JSON是JavaScript Object Notation,下面就简单记录下它。
语法
JSON可以表示三种类型的值:简单值、对象、数组。
1 | // 简单值举例 |
这里唯一要注意的就是,属性名或字符串必须用双引号。
早期的JSON解析器基本是使用JavaScript的eval()
函数,因为JSON是JavaScript语法的子集,所以eval()
可以解析、解释并返回JavaScript对象和数组。后面ECMAScript5进行了规范,定义了全局对象JSON
,它有序列化方法和解析方法。
序列化
JSON.stringify()
将JavaScript对象序列化为JSON字符串。默认结果不含任何空格和缩进。
1 | const book = { |
个性化的JSON.stringify()
可以接收2个额外的参数:
筛选字段的过滤器
可以是筛选属性名的数组,也可以是参数为key
和value
的自定义函数。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26/*
传入数组
"{"title":"Professional JavaScript","edition":3}"
*/
const jsonText1 = JSON.stringify(book, ["title", "edition"]);
/*
传入函数
"{"title":"Professional JavaScript","authors":"Nicholas C. Zakas","year":5000}"
*/
const jsonText2 = JSON.stringify(book, function(key, value) {
switch(key) {
case "authors":
return value.join(",");
case "year":
return 5000;
case "edition":
return undefined; // 值为undefined的属性不会被序列化
default:
return value;
}
});表示是否保留缩进的选项
可以是表示缩进空格数的数字,也可以是用作缩进的字符串。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31// 缩进选项
/*
传入数字
"{
"title": "Professional JavaScript",
"authors": [
"Nicholas C. Zakas"
],
"edition": 3,
"year": 2011
}"
*/
const jsonText1 = JSON.stringify(book, null, 4);
/*
传入字符串
"{
--"title": "Professional JavaScript",
--"authors": [
----"Nicholas C. Zakas"
--],
--"edition": 3,
--"year": 2011
}"
*/
const jsonText2 = JSON.stringify(book, null, "--");
有时候JSON.stringify()
还是不能满足需求,这种时候可以通过对象上调用toJSON()
方法来返回自定义的JSON数据格式。
1 | const book = { |
* 序列化顺序
- 如果存在
toJSON()
且能通过它取得有效的值,则调用该方法。否则按照默认顺序执行序列化。 - 如果提供了第二个参数,则使用过滤器,传入过滤器的值是(1)返回的值。
- 对(2)返回的每个值进行序列化。
- 如果提供了第三个参数,执行相应的格式化。
解析
JSON.parse()
将JSON字符串解析成JavaScript对象。
1 | const book = ...; |
当然,JSON.parse()
也可以接收一个函数作为参数,与过滤函数(replacer)对应,叫做还原函数(reviver)。这个函数也是接收key
和value
作为参数,通常用于把一些序列化了的内容还原成相应对象,譬如将日期字符串转换为Date
对象等,举例如下。
1 | const book = { |