2025-04-13 日报 Day155

2025-04-13 日报 Day155

Yuyang 前端小白🥬

今日的鸡汤

我们常说,生活没有标准答案,每个人都有自己的注脚。面对困境,我们也各有各的选择。“行到水穷处,坐观云起时”是选择,“卧薪尝胆,三千越甲可吞吴”是选择,当然,你也可以选择带上拳套,奋力搏击。

今日学习内容

1、JS 红皮书 P703-710 第二十三章:JSON

今日笔记

1、JSON 是 JavaScript 的严格子集,利用 JavaScript 中的几种模式来表示结构化数据。Crockford 将 JSON 作为替代 XML 的一个方案提出,因为 JSON 可以直接传给 eval()而不需要创建 DOM。
JSON 也不是只能在 JavaScript 中使用,它是一种通用数据格式。很多语
言都有解析和序列化 JSON 的内置能力。
2、JSON的语法: JSON 语法支持表示 3 种类型的值。
 简单值:字符串、数值、布尔值和 null 可以在 JSON 中出现,就像在 JavaScript 中一样。特殊值 undefined 不可以。
 对象:第一种复杂数据类型,对象表示有序键/值对。每个值可以是简单值,也可以是复杂类型。
 数组:第二种复杂数据类型,数组表示可以通过数值索引访问的值的有序列表。数组的值可以是任意类型,包括简单值、对象,甚至其他数组。
JSON 没有变量、函数或对象实例的概念。JSON 的所有记号都只为表示结构化数据,虽然它借用了JavaScript 的语法,但是千万不要把它跟 JavaScript 语言混淆。

  • 简单值: 最简单的 JSON 可以是一个数值。例如,下面这个数值是有效的 JSON:
    5
    这个 JSON 表示数值 5。类似地,下面这个字符串也是有效的 JSON:
    “Hello world!”
    JavaScript 字符串与 JSON 字符串的主要区别是,JSON 字符串必须使用双引号(单引号会导致语法错误)。
    布尔值和 null 本身也是有效的 JSON 值。不过,实践中更多使用 JSON 表示比较复杂的数据结构,其中会包含简单值。
  • 对象: 对象使用与 JavaScript 对象字面量略为不同的方式表示。以下是 JavaScript 中的对象字面量:
    let person = {
    name: “Nicholas”,
    age: 29
    };
    虽然这对 JavaScript 开发者来说是标准的对象字面量,但 JSON 中的对象必须使用双引号把属性名包围起来。下面的代码与前面的代码是一样的:
    let object = {
    “name”: “Nicholas”,
    “age” : 29
    };
  • 数组: JSON 的第二种复杂数据类型是数组。数组在 JSON 中使用 JavaScript 的数组字面量形式表示。例如,以下是一个 JavaScript 数组:
    let values = [25, “hi”, true];
    在 JSON 中可以使用类似语法表示相同的数组:
    [25, “hi”, true]
    3、解析与序列化: JSON 的迅速流行并不仅仅因为其语法与 JavaScript 类似,很大程度上还因为 JSON 可以直接被解析成可用的 JavaScript 对象。JSON 出现之后就迅速成为了 Web 服务的事实序列化标准。
  • JSON对象: 早期的 JSON 解析器基本上就相当于 JavaScript 的 eval()函数。因为 JSON 是 JavaScript 语法的子集,所以 eval()可以解析、解释,并将其作为 JavaScript 对象和数组返回。ECMAScript 5 增加了 JSON全局对象,正式引入解析 JSON 的能力。这个对象在所有主流浏览器中都得到了支持。旧版本的浏览器可以使用垫片脚本(参见 GitHub 上 douglascrockford/JSON-js 中的 JSON in JavaScript)。考虑到直接执行代码的风险,最好不要在旧版本浏览器中只使用 eval()求值 JSON。这个 JSON 垫片脚本最好只在浏览器原生不支持 JSON 解析时使用。
    JSON对象有两个方法: stringify()和 parse()。这两个方法分别用于序列化和解析 JSON。
    在序列化 JavaScript 对象时,所有函数和原型成员都会有意地在结果中省略。此外,值为 undefined
    的任何属性也会被跳过。最终得到的就是所有实例属性均为有效 JSON 数据类型的表示。
    如果给 JSON.parse()传入的 JSON 字符串无效,则会导致抛出错误。
  • 序列化选项: ,JSON.stringify()方法除了要序列化的对象,还可以接收两个参数。这两个参数可以用于指定其他序列化 JavaScript 对象的方式。第一个参数是过滤器,可以是数组或函数;第二个参数是用于缩进结果 JSON 字符串的选项。单独或组合使用这些参数可以更好地控制 JSON 序列化。
    过滤结果: 如果第二个参数是一个数组,那么 JSON.stringify()返回的结果只会包含该数组中列出的对象属性。比如下面的例子:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    let book = { 
    title: "Professional JavaScript",
    authors: [
    "Nicholas C. Zakas",
    "Matt Frisbie"
    ],
    edition: 4,
    year: 2017
    };
    let jsonText = JSON.stringify(book, ["title", "edition"]);
    在这个例子中,JSON.stringify()方法的第二个参数是一个包含两个字符串的数组:”title”和”edition”。它们对应着要序列化的对象中的属性,因此结果 JSON 字符串中只会包含这两个属性:
    {“title”:”Professional JavaScript”,”edition”:4}
    如果第二个参数是一个函数,则行为又有不同。提供的函数接收两个参数:属性名(key)和属性值(value)。可以根据这个 key 决定要对相应属性执行什么操作。这个 key 始终是字符串,只是在值不属于某个键/值对时会是空字符串。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    let book = { 
    title: "Professional JavaScript",
    authors: [
    "Nicholas C. Zakas",
    "Matt Frisbie"
    ],
    edition: 4,
    year: 2017
    };
    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;
    }
    });
    最终得到的 JSON 字符串是这样的:
    {“title”:”Professional JavaScript”,”authors”:”Nicholas C. Zakas,Matt
    Frisbie”,”year”:5000}
  • 字符串缩进: JSON.stringify()方法的第三个参数控制缩进和空格。在这个参数是数值时,表示每一级缩进的空格数。例如,每级缩进 4 个空格,可以这样:
    let book = {
    title: “Professional JavaScript”,
    authors: [
    “Nicholas C. Zakas”,
    “Matt Frisbie”
    ],
    edition: 4,
    year: 2017
    };
    let jsonText = JSON.stringify(book, null, 4);
    这样得到的 jsonText 格式如下:
    {
    “title”: “Professional JavaScript”,
    “authors”: [
    “Nicholas C. Zakas”,
    “Matt Frisbie”
    ],
    “edition”: 4,
    “year”: 2017
    }
    如果缩进参数是一个字符串而非数值,那么 JSON 字符串中就会使用这个字符串而不是空格来缩进。使用字符串,也可以将缩进字符设置为 Tab 或任意字符,如两个连字符:
    用字符串,也可以将缩进字符设置为 Tab 或任意字符,如两个连字符:
    let jsonText = JSON.stringify(book, null, “–” );
    这样,jsonText 的值会变成如下格式:
    {
    –”title”: “Professional JavaScript”,
    –”authors”: [
    —-“Nicholas C. Zakas”,
    —-“Matt Frisbie”
    –],
    –”edition”: 4,
    –”year”: 2017
    }
  • toJSON()方法: 对象需要在 JSON.stringify()之上自定义 JSON 序列化。此时,可以在要序列化的对象中添加 toJSON()方法,序列化时会基于这个方法返回适当的 JSON 表示。事实上,原生 Date 对象就有一个 toJSON()方法,能够自动将 JavaScript 的 Date 对象转换为 ISO 8601 日期字符串(本质上与在Date 对象上调用 toISOString()方法一样)。
    下面的对象为自定义序列化而添加了一个 toJSON()方法:
    let book = {
    title: “Professional JavaScript”,
    authors: [
    “Nicholas C. Zakas”,
    “Matt Frisbie”
    ],
    edition: 4,
    year: 2017,
    toJSON: function() {
    return this.title;
    }
    };
    let jsonText = JSON.stringify(book);
    这里 book 对象中定义的 toJSON()方法简单地返回了图书的书名(this.title)。
    4、解析选项: JSON.parse()方法也可以接收一个额外的参数,这个函数会针对每个键/值对都调用一次。为区别于传给 JSON.stringify()的起过滤作用的替代函数(replacer),这个函数被称为还原函数(reviver)。实际上它们的格式完全一样,即还原函数也接收两个参数,属性名(key)和属性值(value),另外也需要返回值。
    如果还原函数返回 undefined,则结果中就会删除相应的键。如果返回了其他任何值,则该值就会成为相应键的值插入到结果中。还原函数经常被用于把日期字符串转换为 Date 对象。例如:
    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());
    5、小结: JSON 是一种轻量级数据格式,可以方便地表示复杂数据结构。这个格式使用 JavaScript 语法的一个子集表示对象、数组、字符串、数值、布尔值和 null。虽然 XML 也能胜任同样的角色,但 JSON 更简洁,JavaScript 支持也更好。更重要的是,所有浏览器都已经原生支持全局 JSON 对象。
    ECMAScript 5 定义了原生 JSON 对象,用于将 JavaScript 对象序列化为 JSON 字符串,以及将 JSON数组解析为 JavaScript 对象。JSON.stringify()和 JSON.parse()方法分别用于实现这两种操作。这两个方法都有一些选项可以用来改变默认的行为,以实现过滤或修改流程。
此页目录
2025-04-13 日报 Day155