# 处理JSON

理解 JSON 最关键的一点是要把它当成一种数据格式,而不是编程语言。JSON 不属于 JavaScript,它们只是拥有相同的语法而已。JSON 也不是只能在 JavaScript 中使用,它是一种通用数据格式。很多语言都有解析和序列化 JSON 的内置能力。

# 1、语法

JSON 语法支持表示 3 种类型的值。

  • 简单值:字符串、数值、布尔值和 null 可以在 JSON 中出现,就像在 JavaScript 中一样。特殊值 undefined 不可以。
  • 对象:第一种复杂数据类型,对象表示有序键/值对。每个值可以是简单值,也可以是复杂类型。
  • 数组:第二种复杂数据类型,数组表示可以通过数值索引访问的值的有序列表。数组的值可以是任意类型,包括简单值、对象,甚至其他数组。

JSON 没有变量、函数或对象实例的概念。JSON 的所有记号都只为表示结构化数据,虽然它借用了 JavaScript 的语法,但是千万不要把它跟 JavaScript 语言混淆。

# 1.1 简单值

最简单的 JSON 可以是一个数值。例如,下面这个数值是有效的 JSON:

5

// 或者字符串
"Hello world!"
1
2
3
4

JavaScript 字符串与 JSON 字符串的主要区别是,JSON 字符串必须使用双引号(单引号会导致语法错误)

布尔值和 null 本身也是有效的 JSON 值。不过,实践中更多使用 JSON 表示比较复杂的数据结构,其中会包含简单值。

# 1.2 对象

JSON 中的对象必须使用双引号把属性名包围起来

{ 
 "name": "Nicholas", 
 "age": 29 
} 
1
2
3
4

# 1.3 数组

[25, "hi", true]
1

# 2、解析与序列化

JSON 的迅速流行并不仅仅因为其语法与 JavaScript 类似,很大程度上还因为 JSON 可以直接被解析成可用的 JavaScript 对象。

# 2.1 JSON 对象

JSON 对象有两个方法:stringify() 和 parse()。在简单的情况下,这两个方法分别可以将 JavaScript 序列化为 JSON 字符串,以及将 JSON 解析为原生 JavaScript 值。

默认情况下,JSON.stringify() 会输出不包含空格或缩进的 JSON 字符串。

在序列化 JavaScript 对象时,所有函数和原型成员都会有意地在结果中省略。此外,值为 undefined 的任何属性也会被跳过。

# 2.2 序列化选项

实际上,JSON.stringify() 方法除了要序列化的对象,还可以接收两个参数。这两个参数可以用于指定其他序列化 JavaScript 对象的方式。第一个参数是过滤器,可以是数组或函数;第二个参数是用于缩进结果 JSON 字符串的选项。

let book = { 
 title: "Professional JavaScript", 
 authors: [ 
 "Nicholas C. Zakas", 
 "Matt Frisbie" 
 ], 
 edition: 4, 
 year: 2017 
}; 
let jsonText = JSON.stringify(book, ["title", "edition"]); 
// {"title":"Professional JavaScript","edition":4} 

// 使用函数
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; 
  } 
});
// {"title":"Professional JavaScript","authors":"Nicholas C. Zakas,Matt Frisbie","year":5000} 

// 控制缩进
let jsonText = JSON.stringify(book, null, 4);
// { 
//     "title": "Professional JavaScript", 
//     "authors": [ 
//     "Nicholas C. Zakas", 
//     "Matt Frisbie" 
//     ], 
//     "edition": 4, 
//     "year": 2017 
// } 
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
32
33
34
35
36
37
38

# 2.3 解析选项

JSON.parse() 方法也可以接收一个额外的参数,这个函数会针对每个键/值对都调用一次。为区别于传给 JSON.stringify() 的起过滤作用的替代函数(replacer),这个函数被称为还原函数(reviver)。

let book = { 
 title: "Professional JavaScript", 
 authors: [ 
 "Nicholas C. Zakas", 
 "Matt Frisbie" 
 ], 
 edition: 4, 
 year: 2017, 
 releaseDate: new Date(2017, 11, 1) 
}; 
let jsonText = JSON.stringify(book); 
let bookCopy = JSON.parse(jsonText, 
 (key, value) => key == "releaseDate" ? new Date(value) : value); 
alert(bookCopy.releaseDate.getFullYear());
1
2
3
4
5
6
7
8
9
10
11
12
13
14
上次更新: 3/9/2022, 6:56:39 PM