# JSON对象

# 1、简介

JavaScript 对象表示法(JSON)是用于将结构化数据表示为 JavaScript 对象的标准格式,通常用于在网站上表示和传输数据(例如从服务器向客户端发送一些数据,因此可以将其显示在网页上)。

JSON是一种按照 JavaScript 对象语法的数据格式,虽然它是基于 JavaScript 语法,但它独立于 JavaScript,这也是为什么许多程序环境能够读取(解读)和生成 JSON。

JSON 可以作为一个对象或者字符串存在,前者用于解读 JSON 中的数据,后者用于通过网络传输 JSON 数据。这不是一个大事件——JavaScript 提供一个全局的 可访问的 JSON 对象来对这两种数据进行转换。

一个 JSON 对象可以被储存在它自己的文件中,这基本上就是一个文本文件,扩展名为 .json,还有 MIME type 用于 application/json.

# 2、注意事项

  • JSON 是一种纯数据格式,它只包含属性,没有方法。
  • JSON 要求在字符串和属性名称周围使用双引号。单引号无效。
  • 甚至一个错位的逗号或分号就可以导致 JSON 文件出错。您应该小心的检查您想使用的数据 (虽然计算机生成的 JSON 很少出错,只要生成程序正常工作)。
  • JSON 可以将任何标准合法的 JSON 数据格式化保存,不只是数组和对象。比如,一个单一的字符串或者数字可以是合法的 JSON 对象。虽然不是特别有用处……
  • 与 JavaScript 代码中对象属性可以不加引号不同,JSON 中只有带引号的字符串可以用作属性。

# 3、JSON.parse()

JSON.parse() 方法用来解析 JSON 字符串,构造由字符串描述的 JavaScript 值或对象。提供可选的 reviver 函数用以在返回之前对所得到的对象执行变换 (操作)。

语法: JSON.parse(text[, reviver])

const str = '{"P":5}';
const ret = JSON.parse(str, (k, v) => {
  if (k === '') return v; //如果到了最顶层,则直接返回属性值,
  return v * 2; // 否则将属性值变为原来的 2 倍。
});
console.log(ret);// {P: 10}

# 4、JSON.stringify()

JSON.stringify() 方法将一个 JavaScript 对象或值转换为 JSON 字符串,如果指定了一个 replacer 函数,则可以选择性地替换值,或者指定的 replacer 是数组,则可选择性地仅包含数组指定的属性。

语法: JSON.stringify(value[, replacer [, space]])

  • replacer 可选

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

  • space 可选

    指定缩进用的空白字符串,用于美化输出(pretty-print);如果参数是个数字,它代表有多少的空格;上限为 10。该值若小于 1,则意味着没有空格;如果该参数为字符串(当字符串长度超过 10 个字母,取其前 10 个字母),该字符串将被作为空格;如果该参数没有提供(或者为 null),将没有空格。

# 4.1、注意点

  • 如果一个被序列化的对象拥有 toJSON 方法,那么该 toJSON 方法就会覆盖该对象默认的序列化行为:不是该对象被序列化,而是调用 toJSON 方法后的返回值会被序列化

    const obj = {
      x: 1,
      y: false,
      toJSON: function () {
        return 'x: 1, y: false';
      }
    };
    console.log(JSON.stringify(obj));// "x: 1, y: false"
    
  • 非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中。

  • 布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值。

  • undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略(出现在非数组对象的属性值中时)或者被转换成 null(出现在数组中时)。函数、undefined 被单独转换时,会返回 undefined,如JSON.stringify(function(){}) or JSON.stringify(undefined).

  • 对包含循环引用的对象(对象之间相互引用,形成无限循环)执行此方法,会抛出错误。

  • 所有以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们。

  • Date 日期调用了 toJSON() 将其转换为了 string 字符串(同 Date.toISOString()),因此会被当做字符串处理。

    const obj = {
      x: 1,
      d: new Date(2022, 1 - 1, 1, 0, 0, 0, 0)
    };
    console.log(JSON.stringify(obj)); // '{"x":1,"d":"2021-12-31T16:00:00.000Z"}'
    
  • NaN 和 Infinity 格式的数值及 null 都会被当做 null。

  • 其他类型的对象,包括 Map/Set/WeakMap/WeakSet,仅会序列化可枚举的属性。

# 4.2 replacer 参数

replacer 参数可以是一个函数或者一个数组。作为函数,它有两个参数,键(key)和值(value),它们都会被序列化。

在开始时,replacer 函数会被传入一个空字符串作为 key 值,代表着要被 stringify 的这个对象。随后每个对象或数组上的属性会被依次传入。

函数应当返回 JSON 字符串中的 value, 如下所示:

  • 如果返回一个 Number, 转换成相应的字符串作为属性值被添加入 JSON 字符串。
  • 如果返回一个 String, 该字符串作为属性值被添加入 JSON 字符串。
  • 如果返回一个 Boolean, "true" 或者 "false" 作为属性值被添加入 JSON 字符串。
  • 如果返回任何其他对象,该对象递归地序列化成 JSON 字符串,对每个属性调用 replacer 方法。除非该对象是一个函数,这种情况将不会被序列化成 JSON 字符串。
  • 如果返回 undefined,该属性值不会在 JSON 字符串中输出。

注意: 不能用 replacer 方法,从数组中移除值(values),如若返回 undefined 或者一个函数,将会被 null 取代。

function示例

const obj = {
  name: 'Cloud',
  age: 16,
  sex: 1,
  xxx: undefined
};
// 过滤所有属性值是字符串的内容
const objStr = JSON.stringify(obj, (key, value) => {
  if (typeof value === 'string') {
    return undefined;
  }
  return value;
});
console.log(objStr); // {"age":16,"sex":1}

数组实例

如果 replacer 是一个数组,数组的值代表将被序列化成 JSON 字符串的属性名。

const foo = {
  year: 2023,
  month: 9,
  day: 1
};
console.log(JSON.stringify(foo, ['year', 'month'])); // {"year":2023,"month":9}

# 4.3 space 参数

space 参数用来控制结果字符串里面的间距。如果是一个数字,则在字符串化时每一级别会比上一级别缩进多这个数字值的空格(最多 10 个空格);如果是一个字符串,则每一级别会比上一级别多缩进该字符串(或该字符串的前 10 个字符)。

可以用于输出相对容易查看结构的对象图

const a = JSON.stringify(
  {
    x: 1,
    y: {
      x: 2
    }
  },
  null,
  2
);
console.log(a);
/* 
  {
    "x": 1,
    "y": {
      "x": 2
    }
  }
*/

mqyqingfeng (opens new window) stringify MDN (opens new window)

上次更新: 1/22/2025, 9:39:13 AM