likes
comments
collection
share

第六章 JavaScript标准库 6.8 JSON

作者站长头像
站长
· 阅读数 46

6.8 JSON

JSON 格式

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,通常用于 Web 应用程序之间的数据传输。它的历史可以追溯到 20 世纪 90 年代初期,当时网景公司(Netscape)开发了 JavaScript 语言和 JavaScript 对象表示法(JavaScript Object Notation,简称 JSON),用于在浏览器和服务器之间传递数据。 在当时,XML 是主流的数据交换格式,但是 XML 的缺点是比较臃肿、复杂,不适合在 Web 应用程序中使用。与之相比,JSON 具有更小的体积、更简单的语法、更高的性能,因此被广泛采用。 JSON 最初是由 Douglas Crockford 发明的,他在 2002 年发布了第一个 JSON 规范。随着时间的推移,JSON 逐渐成为一种广泛接受的标准,被广泛应用于 Web 开发、移动应用、物联网等领域。目前,JSON 已经成为各种编程语言和平台的通用数据交换格式,比如 JavaScript、Python、Java、C#等。 JSON 格式的规范如下:

  • 1 数据类型 JSON 格式只支持字符串、数字、布尔、对象、数组和 null 数据类型,不支持 JavaScript 中的 Date、RegExp、Function 等复杂类型。以下是一个不符合规范的 JSON 数据,因为包含了 Date 类型。 { "name": "John", "birthday": new Date() }
  • 2 键值的规范 JSON 的基本单元是键值对。一个键值对包括一个键(字符串)和一个值(可以是任意类型的数据)。键和值之间用冒号(:)分隔,多个键值对之间用逗号(,)分隔。例如:
{
  "name": "Tom",
  "age": 20,
  "isStudent": true,
  "hobbies": ["reading", "music"]
}

注意,键名必须是双引号扩起来,数组或者对象的最后一个成员后面不能加逗号,字符串也必须用双引号,不能用单引号。看下面不合法的例子: 例 1: 键名 name 和 age 没有用双引号括起来 { name: "John", age: 25 } 例 2: 数组或对象最后一个成员后面加上逗号

[1, 2, 3,]

{
  "name": "Tom",
  "age": 20,
}

例 3: 键名和字符串值必须使用双引号,不能使用单引号 { "name": 'John', "age": 25 }

JSON 格式和前面讲到的对象字面量的很相似,但是他们有如下区别:

  • 1 字符串表示:在 JSON 中,键名必须是双引号括起来的字符串,而在 JavaScript 中,键名可以是不带引号的标识符或字符串(如果包含特殊字符或空格,则需要使用引号括起来)。
  • 2 值表示:JSON 中只支持简单类型的值,例如字符串、数字、布尔、null、对象和数组。而 JavaScript 中的对象字面量可以包含复杂类型的值,例如函数、日期对象和正则表达式对象等。
  • 3 注释:在 JSON 中不支持注释,而在 JavaScript 中可以使用注释。

JSON.stringify

JSON.stringify() 方法将 JavaScript 对象转换为 JSON 字符串。 语法: JSON.stringify(value[, replacer[, space]]) 参数:

  • 1 value:必选参数,即要转换的 JavaScript 对象或值。
  • 2 replacer:可选参数,用于控制 JSON.stringify() 如何转换对象的函数。
  • 3 space:可选参数,用于控制缩进的空格数量。 返回值: 一个表示给定 JavaScript 对象的 JSON 字符串。 示例: JSON.stringify(value[, replacer[, space]])
const obj = {
  name: 'John',
  age: 30,
  city: 'New York',
};

const jsonString = JSON.stringify(obj);
console.log(jsonString);
// 输出: {"name":"John","age":30,"city":"New York"}

在上面的示例中,我们定义了一个 JavaScript 对象,然后使用 JSON.stringify() 方法将其转换为 JSON 格式的字符串,并将其输出到控制台。

  • replacer 参数 使用 replacer 参数可以控制序列化过程中的属性过滤或转换操作。replacer 参数可以是一个函数或一个数组。 如果 replacer 参数是一个函数,那么该函数会被调用一次又一次,每次调用时传入两个参数:
  • key:当前属性的名称。
  • value:当前属性的值。 函数可以返回一个新值,或返回 undefined,以将属性从序列化中删除。以下示例使用一个函数来将日期对象转换为字符串:
const obj = {
  name: 'John',
  age: 30,
  city: 'New York',
  birthdate: new Date('1992-10-15'),
};

const jsonString = JSON.stringify(obj, (key, value) => {
  if (key === 'birthdate') {
    return value.toISOString().substring(0, 10);
  }
  return value;
});

console.log(jsonString);
// 输出: {"name":"John","age":30,"city":"New York","birthdate":"1992-10-15"}

在上面的示例中,我们定义了一个包含日期对象的 JavaScript 对象,并使用 JSON.stringify() 将其转换为 JSON 格式的字符串。我们使用一个函数作为 replacer 参数,该函数在处理到 birthdate 属性时,将日期对象转换为 ISO 格式的字符串。输出的 JSON 字符串中,birthdate 属性的值已经被转换为字符串了。 如果 replacer 参数是一个数组,那么它包含了要序列化的属性名称,序列化时仅序列化该数组中列出的属性。例如,以下示例仅序列化 name 和 age 两个属性:

const obj = {
  name: 'John',
  age: 30,
  city: 'New York',
};

const jsonString = JSON.stringify(obj, ['name', 'age']);

console.log(jsonString);
// 输出: {"name":"John","age":30}

在上面的示例中,我们使用一个数组作为 replacer 参数,该数组中只包含 name 和 age 两个属性的名称。因此,在转换为 JSON 字符串时,仅包含这两个属性的信息。

  • space 参数 space 参数可以是一个数字或一个字符串。 如果 space 参数是一个数字,它定义了每个缩进级别应该包含多少个空格字符。例如,以下示例将 space 参数设置为 2:
const obj = {
  name: 'John',
  age: 30,
  city: 'New York',
};

const jsonString = JSON.stringify(obj, null, 2);

console.log(jsonString);
/*
输出:
{
  "name": "John",
  "age": 30,
  "city": "New York"
}
*/

在上面的示例中,我们使用 JSON.stringify() 将 JavaScript 对象转换为 JSON 格式的字符串,并将 space 参数设置为 2。输出的字符串包含了缩进,并且每个缩进级别包含了两个空格字符。 如果 space 参数是一个字符串,它将用作缩进字符。例如,以下示例将 space 参数设置为一个包含四个空格字符的字符串:

const obj = {
  name: 'John',
  age: 30,
  city: 'New York',
};

const jsonString = JSON.stringify(obj, null, '    ');

console.log(jsonString);
/*
输出:
{
    "name": "John",
    "age": 30,
    "city": "New York"
}
*/

在上面的示例中,我们将 space 参数设置为一个包含四个空格字符的字符串。输出的字符串中每个缩进级别都包含了四个空格字符。 对不支持的参数类型的处理 如果在序列化过程中遇到了不支持的数据类型,JSON.stringify() 方法会自动将它们转换为 null 值。这包括以下几种情况:

  • 1 undefined 、函数类型、Symbol 类型,key 将会被忽略。
  • 2 NaN 和 Infinity,将被转换为 null 值。
  • 3 Date 对象,将被转换为 ISO 格式的字符串(例如:"2022-04-10T10:30:00.000Z")。
  • 4 RegExp 对象,将被转换为空对象{}。 以下是一个示例,展示了如何将一个包含不支持数据类型的对象转换为 JSON 格式的字符串:
const obj = {
  name: 'John',
  age: 30,
  birthday: new Date(),
  skills: ['JavaScript', 'HTML', 'CSS'],
  sayHello: function () {
    console.log('Hello!');
  },
  favoriteColor: undefined,
  favoriteFood: null,
  favoriteAnimal: Symbol('lion'),
  testNaN: NaN,
  testInfinity: Infinity,
  testRegExp: /\d+/,
};

console.log(JSON.stringify(obj));
/*
输出:
{"name":"John","age":30,"birthday":"2023-04-11T05:12:21.508Z","skills":["JavaScript","HTML","CSS"],"favoriteFood":null,"testNaN":null,"testInfinity":null,"testRegExp":{}}
*/

JSON.parse

JSON.parse() 方法可以将符合 JSON 格式的字符串解析为对应的 JavaScript 对象或数组或字符串。其语法如下: JSON.parse(text[, reviver]) 其中,text 参数是需要解析的 JSON 字符串;reviver 参数是一个可选的函数,用于在解析过程中对属性值进行转换操作。 下面是一个简单的示例,展示了如何将一个 JSON 格式的字符串解析为 JavaScript 对象:

const jsonString =
  '{"name":"John","age":30,"skills":["JavaScript","HTML","CSS"],"isMarried":false}';
const obj = JSON.parse(jsonString);
console.log(obj);
/*
输出:
{
  name: "John",
  age: 30,
  skills: ["JavaScript", "HTML", "CSS"],
  isMarried: false
}
*/

在上面的示例中,我们使用 JSON.parse() 方法将一个 JSON 格式的字符串解析为了对应的 JavaScript 对象,并将其存储在变量 obj 中。最后,我们将 obj 打印到控制台上,可以看到其与原始的 JSON 字符串相对应。 除了解析简单的 JSON 对象外,JSON.parse() 方法还可以解析包含更复杂数据结构的 JSON 字符串,例如嵌套的对象和数组。 reviver 参数是一个可选的函数,用于在解析 JSON 字符串的过程中对属性值进行转换操作。reviver 函数接受两个参数:属性名和属性值。在解析 JSON 字符串的过程中,每次遇到一个属性名和属性值,都会调用 reviver 函数进行转换操作,并将转换后的结果作为属性值保存在解析出来的 JavaScript 对象或数组中。 下面是一个示例,展示了如何使用 reviver 函数对解析出来的 JavaScript 对象进行转换操作。假设我们有一个 JSON 字符串,表示一个学生的信息: const jsonString = '{"name":"John","age":30,"grades":{"math":80,"science":90,"english":85}}'; 现在,我们想要将这个 JSON 字符串解析为对应的 JavaScript 对象,并将其中的成绩按百分制转换为等级制(A、B、C、D、E)。我们可以编写如下的 reviver 函数:

function gradeReviver(key, value) {
  if (typeof value === 'number') {
    // 如果属性值是数字,则将其转换为等级制
    if (value >= 90) {
      return 'A';
    } else if (value >= 80) {
      return 'B';
    } else if (value >= 70) {
      return 'C';
    } else if (value >= 60) {
      return 'D';
    } else {
      return 'E';
    }
  } else {
    // 其他情况直接返回属性值
    return value;
  }
}

上面的 gradeReviver 函数其主要功能是将 JSON 字符串中的数字转换为等级制,并将转换后的结果存储在解析出来的 JavaScript 对象或数组中。

转载自:https://juejin.cn/post/7243451555931176997
评论
请登录