关于javascript:快速了解JavaScript的JSON

47次阅读

共计 6047 个字符,预计需要花费 16 分钟才能阅读完成。

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 之间互相转换。

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

正文完
 0