一、语法
- JSON语法支持表示3种类型的值:
- 简单值:字符串、数值、布尔值和null可以在JSON中出现,就像在JavaScript中一样。特殊值undefined不可以。
- 对象:第一种复杂数据类型,对象表示有序键/值对。每个值可以是简单值,也可以是复杂类型。
- 数组:第二种复杂数据类型,数组表示可以通过数值索引访问的值的有序列表。数组的值可以是任意类型,包括简单值、对象,甚至其他数组。
- JSON没有变量声明。
- JSON没有变量、函数或对象实例的概念。JSON的所有记号都只为表示结构化数据
- 布尔值和null本身也是有效的JSON值。
- JavaScript字符串与JSON字符串的主要区别是:JSON字符串必须使用双引号。
- 数组在 JSON 中使用 JavaScript 的数组字面量形式表示。
二、解析与序列化
1、JSON对象
- stringify()和parse()方法可用于将JavaScript序列化为JSON字符串,以及将JSON解析为原生JavaScript值。
- 如果给JSON.parse()传入的JSON字符串无效,则会导致抛出错误。
1 2 3 4 5 6 7 8 9 10 11 12 13
| let book = { title: "Professional JavaScript", authors: [ "Nicholas C. Zakas", "Matt Frisbie" ], edition: 4, year: 2017 }; let jsonText = JSON.stringify(book);
|
2、序列化选项
- JSON.stringify()方法除了要序列化的对象,还可以接收两个参数。这两个参数可以用于指定其他序列化JavaScript对象的方式。
- 第一个参数是过滤器,可以是数组或函数;
- 第二个参数是用于缩进结果JSON字符串的选项。
- 单独或组合使用这些参数可以更好地控制JSON序列化。
1)过滤结果
- 如果第二个参数是一个数组,那么JSON.stringify()返回的结果只会包含该数组中列出的对象属性。
1 2 3 4 5 6 7 8 9 10 11 12 13
| let book = { title: "Professional JavaScript", authors: [ "Nicholas C. Zakas", "Matt Frisbie" ], edition: 4, year: 2017 }; let jsonText = JSON.stringify(book, ["title", "edition"]);
|
- 如果第二个参数是一个函数,提供的函数接收两个参数:属性名(key)和属性值(value)。可以根据这个key决定要对相应属性执行什么操作。
- 函数过滤器会应用到要序列化的对象所包含的所有对象,因此如果数组中包含多个具有这些属性的对象,则序列化之后每个对象都只会剩下上面这些属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| let book = { title: "Professional JavaScript", authors: [ "Nicholas C. Zakas", "Matt Frisbie" ], edition: 4, year: 2017 }; let jsonText = JSON.stringify(book, (key, value) => { switch(key) { case "authors": return value.join(",") case "year": return 5000; case "edition": return undefined; default: return value; } });
|
2)字符串缩进
- JSON.stringify()方法的第三个参数控制缩进和空格。
- JSON.stringify()方法还为方便阅读插入了换行符。
- 最大缩进值为10,大于10的值会自动设置为10。
- 如果缩进参数是一个字符串而非数值,那么JSON字符串中就会使用这个字符串而不是空格来缩进。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| let book = { title: "Professional JavaScript", authors: [ "Nicholas C. Zakas", "Matt Frisbie" ], edition: 4, year: 2017 }; let jsonText = JSON.stringify(book, null, 4);
|
3)toJSON()方法
1 2 3 4 5 6 7 8 9 10 11 12 13
| let book = { title: "Professional JavaScript", authors: [ "Nicholas C. Zakas", "Matt Frisbie" ], edition: 4, year: 2017, toJSON: function() { return this.title; } }; let jsonText = JSON.stringify(book);
|
这里book对象中定义的toJSON()方法简单地返回了图书的书名(this.title)。
- 箭头函数不能用来定义toJSON()方法。
- 主要原因是箭头函数的词法作用域是全局作用域,在这种情况下不合适。
- toJSON()方法可以与过滤函数一起使用,在把对象传给JSON.stringify()时会执行如下步骤。
(1)如果可以获取实际的值,则调用toJSON()方法获取实际的值,否则使用默认的序列化。
(2)如果提供了第二个参数,则应用过滤。传人过滤函数的值就是第(1)步返回的值。
(3)第(2)步返回的每个值都会相应地进行序列化。
(4) 如果提供了第三个参数,则相应地进行缩进。
3、解析选项
- JSON.parse()方法也可以接收一个额外的参数,这个函数会针对每个键/值对都调用一次。
- 为区别于传给JSON.stringify()的起过滤作用的替代函数(replacer),这个函数被称为还原函数(reviver)。实际上它们的格式完全一样。