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
    // }
  3. 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;
}
});