JSON 的语法可以表示以下三种类型的值:

  • 简单值
  • 对象
  • 数组

简单值

表示数值:5
表示字符串:”Hello World!”

JavaScript 字符串与 JSON 字符串的最大区别在于,JSON 字符串必须使用双引号(单引号会导致语法错误)

对象

1
2
3
4
5
6
7
8
9
10
11
// javascript
var person = {
name: "jack",
age: 29
};

// json
{
name: "jack",
age: 29
};

在 JSON 中,对象的属性必须加双引号

数组

表示的方法和 JavaScript 一样,可以把对象和数组结合起来,构成更复杂的数据集合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[
{
title: "test1",
year: 2018,
tabs: ["apple", 1, true]
},
{
title: "test2",
year: 2018,
tabs: ["origin", 2, false]
},
{
title: "test3",
year: 2018,
tabs: ["apple", 3, true]
}
];

解析和序列化

1
2
3
4
5
6
7
var book = {
title: "求魔",
author: ["耳根"],
year: 2012
};
var jsonString = JSON.stringify(book); // 把 JavaScript 对象序列化为一个 JSON 字符串
var bookCopy = JSON.parse(jsonString); // 把 JSON 字符串转成 JavaScript 对象,如果字符串不是有效的 JSON ,该方法会抛出错误

在序列化 JavaScript 对象时,值为 undefined 的任何属性都会被跳过。

序列化选项

JSON.stringify()除了要序列化的 JavaScript 对象外,还可以接受两个参数,第一个参数是过滤器,可以为一个数组,也可以为一个函数。第二个参数时一个选项,表示是否在 JSON 字符串中保留缩进。

  1. 过滤结果
    如果过滤器是数组,那么返回的结果只会包含数组中列出的属性
    1
    2
    3
    4
    5
    6
    7
    var book = {
    title: "求魔",
    author: ["耳根"],
    year: 2012
    };
    var jsonString = JSON.stringify(book, ["title", "author"]);
    // {"title":"求魔","author":["耳根"]}
    如果过滤器是函数,则接收两个参数,属性(键)名和属性值,如果函数返回了 undefined,则相应的属性会被忽略。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    var book = {
    title: "求魔",
    author: ["耳根"],
    protagonist: ["苏铭"],
    year: 2012
    };
    var jsonString = JSON.stringify(book, function(key, value) {
    switch (key) {
    case "author":
    return value.join(",");
    case "protagonist":
    return undefined;
    case "year":
    return 3000;
    default:
    return value;
    }
    });
    // {"title":"求魔","author":"耳根","year":3000}
  2. 字符串缩进
    JSON.stringify()方法的第三个参数用于控制结果中的缩进和空白符。如果这个参数是一个数值,那它表示的是每个级别缩进的空格数。如果是一个字符串,那么缩进字符就会设置为所写的字符串

缩进的大小最大为 10,如果超过 10,会自动转成 10,字符串只会选取前面 10 个字符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var book = {
title: "求魔",
author: ["耳根"],
year: 2012
};
var jsonString = JSON.stringify(book, null, 4);
// {
// "title": "求魔",
// "author": [
// "耳根"
// ],
// "year": 2012
// }
var jsonString2 = JSON.stringify(book, null, "--");
// {
// --"title": "求魔",
// --"author": [
// ----"耳根"
// --],
// --"year": 2012
// }
  1. toJSON()方法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var book = {
    title: "求魔",
    author: ["耳根"],
    year: 2012,
    toJSON: function() {
    return this.title;
    }
    };
    var jsonString = JSON.stringify(book);
    // jsonString值为字符串:"求魔"

    序列化的内部顺序:
    (1) 如果存在 toJSON() 方法而且能通过它取得有效的值,则调用该方法。否则,返回对象本身。
    (2) 如果提供了第二个参数,应用这个过滤器。传入的值是第 (1) 步返回的值。
    (3) 对第 (2) 步返回的每个值进行相应的格式化。
    (4) 如果提供了第三个参数,执行相应的格式化。

解析选项

JSON.parse()方法也可以接收另一个参数,该参数是一个函数,被称为还原函数(reviver),接收两个参数,key 和 value

1
2
3
4
5
6
7
8
9
10
11
12
13
var book = {
title: "求魔",
author: ["耳根"],
year: new Date(2012, 2, 20)
};
var jsonString = JSON.stringify(book);
var bookCopy = JSON.parse(jsonString, function(key, value) {
if (key === "year") {
return new Date(value);
} else {
return value;
}
});