把它当成一种数据格式,而不是编程语言。JSON 不属于 JavaScript,
它们只是拥有相同的语法而已。JSON 也不是只能在 JavaScript 中使用,它是一种通用数据格式。很多语言都有解析和序列化 JSON 的内置能力。
语法
- 简单值:字符串、数值、布尔值和 null 可以在 JSON 中出现,就像在 JavaScript 中一样。特殊值 undefined 不可以。
- 对象:第一种复杂数据类型,对象表示有序键/值对。每个值可以是简单值,也可以是复杂类型。
- 数组:第二种复杂数据类型,数组表示可以通过数值索引访问的值的有序列表。数组的值可以是任意类型,包括简单值、对象,甚至其他数组。
简单值
JavaScript 字符串与 JSON 字符串的主要区别是,JSON 字符串必须使用双引号(单引号会导致语法错误)。布尔值和 null 本身也是有效的 JSON 值
对象
与 JavaScript 对象字面量相比,JSON 主要有两处不同。首先,没有变量声明(JSON 中没有变量)。其次,最后没有分号(不需要,因为不是 JavaScript 语句)。同样,用引号将属性名包围起来才是有效的JSON。属性的值可以是简单值或复杂数据类型值,后者可以在对象中再嵌入对象.
1 | { |
数组
数组在 JSON 中使用 JavaScript 的数组字面量形式表示.
JavaScript
1 | let values = [25, "hi", true]; |
Json
1 | [25,"hi",true] |
JavaScript序列化为Json
stringfy():在序列化 JavaScript 对象时,所有函数和原型成员都会有意地在结果中省略。此外,值为 undefined的任何属性也会被跳过。最终得到的就是所有实例属性均为有效 JSON 数据类型的表
1 | let book = { |
结果:
{“title”:”Professional JavaScript”,”authors”:[“Nicholas C. Zakas”,”Matt Frisbie”],
“edition”:4,”year”:2017}
还可以接收两个参数。这两个参数可以用于指定其他序列化 JavaScript 对象的方式。第一个参数是过滤器,可以是数组或函数;第二个参数是用于缩进结果 JSON 字符串的选项。
1 | let book = { |
- 如果第二个参数是一个函数,则行为又有不同。提供的函数接收两个参数:属性名(key)和属性值(value)。可以根据这个 key 决定要对相应属性执行什么操作。这个 key 始终是字符串,只是在值
不属于某个键/值对时会是空字符串 - 返回的值就是相应 key 应该包含的结果。注意,返回 undefined 会导致属性被忽略
1 |
|
JSON.stringify()方法的第三个参数控制缩进和空格。在这个参数是数值时,表示每一级缩进的空格数。
1 | let book = { |
toJSON():在要序列化的对象中添加 toJSON()方法,序列化时会基于这个方法返回适当的 JSON 表示:
1 | let book = { |
toJSON()方法可以与过滤函数一起使用,在把对象传给 JSON.stringify()时会执行如下步骤。
(1) 如果可以获取实际的值,则调用 toJSON()方法获取实际的值,否则使用默认的序列化。
(2) 否则,使用默认序列化时,如果提供了第二个参数,则应用过滤。
(3) 第(2)步返回的每个值都会相应地进行序列化。
(4) 如果提供了第三个参数,则相应地进行缩进。
ES6中堆JSON.stringfy的改造
UTF-8 标准规定,0xD800
到0xDFFF
之间的码点,不能单独使用,必须配对使用。比如,\uD834\uDF06
是两个码点,但是必须放在一起配对使用,代表字符𝌆
。这是为了表示码点大于0xFFFF
的字符的一种变通方法。单独使用\uD834
和\uDFO6
这两个码点是不合法的,或者颠倒顺序也不行,因为\uDF06\uD834
并没有对应的字符。
JSON.stringify()
的问题在于,它可能返回0xD800
到0xDFFF
之间的单个码点。
1 | JSON.stringify('\u{D834}') // "\u{D834}" |
为了确保返回的是合法的 UTF-8 字符,ES2019 改变了JSON.stringify()
的行为。如果遇到0xD800
到0xDFFF
之间的单个码点,或者不存在的配对形式,它会返回转义字符串,留给应用自己决定下一步的处理。
1 | JSON.stringify('\u{D834}') // ""\\uD834""JSON.stringify('\uDF06\uD834') // ""\\udf06\\ud834"" |
解析选项
JSON.parse():接收一个参数,这个函数称为还原函数,还原函数接收两个参数,属性名key和属性名value,如果还原函数返回undefined,则结果中删除相应键,如果返回了其他任何值,则该值就会成为相应键的值插入到结果中。
1 | let book = { |