乐趣区

关于javascript:快速了解JavaScript的JSON

JSON(JavaScript Object Notation)是一种通用的、轻量级的数据交换格局,而不是编程语言。因为 XML 过于冗余和啰嗦,因而,应用 JSON 代替 XML 进行网络传输。

一个 JSON 对象能够被贮存在它本人的文件中,这基本上就是一个文本文件,扩大名为 .json

JSON 语法

基本上 JSON 对象就是基于 JavaScript 对象,因而,能够把 JavaScript 对象写入 JSON 数据,JSON 能够将 JavaScript 对象分为三类:

  • 简略值:字符串、数值、布尔值和 nullundefined 除外。
  • 对象:简单的数据类型,对象示意有序键 / 值对。
  • 数组:简单的数据类型,数组示意带有索引的有序列表,能够通过索引拜访数组中的值。

而在 JSON 中,应用如下语法规定:

  • 数据在键 / 值对中,且由逗号分隔。
  • 花括号保留对象,方括号保留数组。
{
    "code": 1,
    "status": true,
    "msg": "Http Request Success",
    "data": [
        {“id”: 2011101010,
            "name": "小赵",
            "age": 29,
            "sex": "男",
            "birthday":“1992-04-09”,
            "address": [
                "北京市通州区万达广场",
                "天津市",
                "河北省邯郸市"
            ]
        },
        {“id”: 2011101011,
            "name": "小钱",
            "age": 27,
            "sex": "男",
            "birthday":“1994-05-01”,
            "address": [
                "北京市通州区万达广场",
                "天津市",
                "河北省邯郸市"
            ]
        },
        {“id”: 2011101013,
            "name": "小玲",
            "age": 28,
            "sex": "女",
            "birthday":“1993-09-26”,
            "address": [
                "北京市通州区万达广场",
                "天津市",
                "河北省邯郸市"
            ]
        }
    ]
}

留神:JSON 简略值中的字符串必须应用双引号标记,因为应用单引号会导致语法错误。

序列化与解析

ECMAScipt 5 增加了用于 JSON 解析与序列化的 JSON 对象,该对象只蕴含两个办法:

  • JSON.stringify():用于将 JavaScript 简略值、对象或数组序列化为 JSON 字符串。
  • JSON.parse():用于将 JSON 格局的字符串解析为原生 JavaScript 值。

上面具体介绍这两种办法。

序列化

JSON.stringify() 办法将一个 JavaScript 简略值、对象或数组转换为 JSON 字符串。如果指定一个 replacer 函数,则能够选择性地替换掉,或者指定的 replacer 的数组,则可选择性地仅蕴含数组指定的属性。

stringify(value, replacer, space): string;
  • value:将要序列化成一个 JSON 字符串的值。
  • replacer:可选参数,用于转换后果的函数或数组。
  • space:可选参数,管制后果中,每个属性的间距,用于丑化输入。
let student = {
    id: 2011101011,
    name: "小钱",
    age: 27,
    sex: undefined,
    birthday: new Date(1994, 5, 1),
    address: [
        "北京市通州区",
        "浙江省杭州市",
        "河北省邯郸市"
    ]
};
let json = JSON.stringify(student);

应用 JSON.stringify() 在默认状况下会输入不蕴含空格或缩进的 JSON 字符串。如下是输入的 JSON 字符串后果:

{"id":2011101011,"name":"小钱","age":27,"birthday":"1994-05-31T16:00:00.000Z","address":["北京市通州区万达广场","天津市","河北省邯郸市"]}

而在序列化时,会无意地将所有函数和原型对象在后果中省略。

留神:值为 undefined 的任何属性都会被省略。

replacer

如果 replacer 是一个函数,则在序列化过程中,被序列化的值的每个属性都会通过该函数的转换和解决;如果该参数是一个数组,则只有蕴含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中;如果该参数为 null 或者未提供,则对象所有的属性都会被序列化。

JSON.stringify() 办法的 replacer 参数用于转换后果。

如果 replacer 是一个数组,那 JSON.stringify() 返回的后果只会蕴含数组中列出的对象属性。如下所示:

let student = {
    id: 2011101011,
    name: "小钱",
    age: 27,
    sex: undefined,
    birthday: new Date(1994, 5, 1),
    address: [
        "北京市通州区",
        "浙江省杭州市",
        "河北省邯郸市"
    ]
};
let json = JSON.stringify(student, ["name", "address"]);

下面的例子,输入的后果会依据第二个参数传入的数组 ["name", "address"] 来获取对应 nameaddress 属性及它们的值进行序列化:

{"name":"小钱","address":["北京市通州区","浙江省杭州市","河北省邯郸市"]}

如果 replacer 是一个函数,它将有键 key 和值 value 两个参数,且依据函数进行相应的序列化操作,且函数返回值该当是 JSON 中 key 对应的 value 值。key 始终是字符串,只在值不属于某个 key 时,才会是空字符串。如下所示:

let student = {
    id: 2011101011,
    name: "小钱",
    age: 27,
    sex: undefined,
    birthday: new Date(1994, 5, 1),
    address: [
        "北京市通州区",
        "浙江省杭州市",
        "河北省邯郸市"
    ]
};
let json = JSON.stringify(student, (key, value) => {console.log(typeof value);
    if (key == "address") {return value.join(",");
    }
    if (key == "birthday") {return undefined;}
    return value;    // 肯定要提供该默认返回值,以返回其它属性传入的值。});

最终失去的 JSON 字符串是这样的:

{"id":2011101011,"name":"小钱","age":27,"address":"北京市通州区, 浙江省杭州市, 河北省邯郸市"}

留神:应用 replacer 序列化失去的 JSON 在应用 parse 进行解析,就只会失去 JSON 中的属性。

space

space 参数用于管制缩进和空格。当该参数为数值时,示意每一级缩进的空格数。如下所示:

let student = {
    id: 2011101011,
    name: "小钱",
    age: 27,
    sex: undefined,
    birthday: new Date(1994, 5, 1),
    address: [
        "北京市通州区",
        "浙江省杭州市",
        "河北省邯郸市"
    ]
}
let json = JSON.stringify(student, null, 4);

输入的 JSON 格局如下所示:

{
    "id": 2011101011,
    "name": "小钱",
    "age": 27,
    "birthday": "1994-05-31T16:00:00.000Z",
    "address": [
        "北京市通州区",
        "浙江省杭州市",
        "河北省邯郸市"
    ]
}

留神:除了缩进,JSON.stringify() 办法还很不便地插入了换行符。最大缩进值为 10,大于 10 的值主动设置为 10;最小缩进值为 1,小于 1 的值意味着没有缩进字符。

当该参数为字符串时,将指定该字符串为空格;如果没有提供,或者值为 null,将没有空格。若两个连字符:

let student = {
    id: 2011101011,
    name: "小钱",
    age: 27,
    sex: undefined,
    birthday: new Date(1994, 5, 1),
    address: [
        "北京市通州区",
        "浙江省杭州市",
        "河北省邯郸市"
    ]
}
let json = JSON.stringify(student, null, "--");

输入的 JSON 格局如下:

{
--"id": 2011101011,
--"name": "小钱",
--"age": 27,
--"birthday": "1994-05-31T16:00:00.000Z",
--"address": [
----"北京市通州区",
----"浙江省杭州市",
----"河北省邯郸市"
--]
}

也能够应用空格 ""、制表符 '\t'Tab来设置缩进字符。如下所示:

let student = {
    id: 2011101011,
    name: "小钱",
    age: 27,
    sex: undefined,
    birthday: new Date(1994, 5, 1),
    address: [
        "北京市通州区",
        "浙江省杭州市",
        "河北省邯郸市"
    ]
}
let json = JSON.stringify(student, null, '\t');

输入的 JSON 格局如下:

{
    "id": 2011101011,
    "name": "小钱",
    "age": 27,
    "birthday": "1994-05-31T16:00:00.000Z",
    "address": [
        "北京市通州区",
        "浙江省杭州市",
        "河北省邯郸市"
    ]
}

留神:应用字符串时同样有 10 个字符的长度限度。如果字符串长度超过 10,则会在第 10 个字符处截断。

toJSON()

如果对象之中定义了 toJSON() 办法,JSON.stringify() 就会调用该对象的 toJSON() 办法,笼罩默认序列化行为。如下所示:

let student = {
    id: 2011101011,
    name: "小钱",
    age: 27,
    sex: undefined,
    birthday: new Date(1994, 5, 1),
    address: [
        "北京市通州区",
        "浙江省杭州市",
        "河北省邯郸市"
    ],
    toJSON: function () {
        return {
            name: this.name,
            age: this.age
        };
    }
}
let json = JSON.stringify(student, null, " ");

输入的 JSON 格局如下:

{
 "name": "小钱",
 "age": 27
}

toJSON() 办法能够返回任意序列化值,都能够起到相应的作用。

留神:箭头函数不能用来定义 toJSON() 办法。次要起因是箭头函数的词法作用域是全局作用域,在这种状况下不适宜。

toJSON() 办法能够与 replacer 一起应用,因而,序列化流程的程序十分重要。在把对象传给 JSON.stringify() 时会执行如下步骤。

  1. 如果定义了 toJSON()办法且能获取到理论值,则调用 toJSON() 办法,否则应用默认的序列化。
  2. 如果定义了 JSON.stringify() 办法的 replacer 函数,则应用 replacer 函数。传入的值就是第 1 步返回的值。
  3. 第 2 步返回的每个值都会相应地进行序列化。
  4. 如果提供了space 参数,则相应地进行缩进。

了解这个程序有助于决定是创立 toJSON() 办法,还是应用 replacer 函数,抑或是两者都用。

解析

JSON.parse() 办法用来解析 JSON 字符串,结构由字符串形容的 JavaScript 值或对象。提供可选的 reviver 函数用以在返回之前对所失去的对象执行变换(操作)。

parse(text, reviver): any;
  • text:要被解析成 JavaScript 值的字符串。
  • reviver:可选参数,用于批改解析生成的原始值。
let json = '{' +
    '"id":2011101011,'+'"name":" 小钱 ",' +
    '"age":27,'+'"birthday":"1994-05-31T16:00:00.000Z",' +
    '"address":['+'" 北京市通州区 ",' +
        '"浙江省杭州市",'+'" 河北省邯郸市 "'+']'+'}'
let student = JSON.parse(json);

输入的对象为:

{
  id: 2011101011,
  name: '小钱',
  age: 27,
  birthday: '1994-05-31T16:00:00.000Z',
  address: ['北京市通州区', '浙江省杭州市', '河北省邯郸市']
}

留神:如果给 JSON.parse() 传入的 JSON 字符串有效,则会抛出异样。

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());

reviver

reviver 参数是一个还原函数,如果指定了还原函数,将解析出的 JavaScript 值通过一次转换后返回最终值。该函数的调用机会在 parse 函数返回之前,并接管 keyvalue 两个参数。如果返回 undefined,后果会删除与 undefined 绝对应的 key;而返回其它值,则该值会成为相应键的值并插入到返回后果中。

let json = '{' +
    '"id":2011101011,'+'"name":" 小钱 ",' +
    '"age":27,'+'"birthday":"1994-05-31T16:00:00.000Z",' +
    '"address":['+'" 北京市通州区 ",' +
        '"浙江省杭州市",'+'" 河北省邯郸市 "'+']'+'}'
let student = JSON.parse(json, (key, value) => {if (key == "birthday") {return new Date(value);
    }
    return value;
});

在下面的代码中,JSON.parse() 办法中,定义了一个还原函数,获取 birthday 键并从新创立新的 Date 对象。最初,student.birthday 属性变成了 Date 对象,能够调用无关 Date 类的办法了。

总结

通过下面的简略介绍,JSON 这种数据结构能够很不便地示意简单的数据结构,如 JavaScript 中的数字、字符串、布尔值、数组、对象和 null 都能够用 JSON 格局示意。且比 XML 更加轻量级。而且,古代浏览器都曾经原生反对全局 JSON 对象,并且应用 JSON.stringify()JSON.parse() 办法实现了 JavaScript 与 JSON 之间互相转换。

更多内容请关注公众号「海人的博客」,回复「资源」即可取得收费学习资源!

退出移动版