JSON.stringify() 序列化字符串的限制

792 阅读2分钟

介绍

JSON.stringify() 是一种将 JavaScript 对象序列化为 JSON 字符串的方法。

语法为:

JSON.stringify(value[, replacer [, space]])
  • value

    将要序列化成 一个 JSON 字符串的值。

  • replacer 可选

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

function replacer(key, value) {
  if (typeof value === "string") {
    return undefined;
  }
  return value;
}

const foo = {foundation: "Mozilla", model: "box", week: 45, transport: "car", month: 7};
const jsonString = JSON.stringify(foo, replacer); // {"week":45,"month":7}

const foo = {
  foundation: "Mozilla",
  model: "box",
  week: 45,
  transport: "car",
  month: 7,
};

JSON.stringify(foo, ["week", "month"]); // {"week":45,"month":7}
  • space 可选

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

  1. 以下是使用该方法深克隆一个简单对象:
const o1 = { a: { b: 1 }, c: 1 };
const o2 = JSON.parse(JSON.stringify(o1));
o1.a.b = 2;
o1.c = 2;
console.log(o2.a.b, o2.c, o1.a === o2.a); // 1 1 false

限制

虽然 JSON.stringify() 可以很方便地将对象转换为 JSON 字符串,但是它有一些限制,需要注意。

  1. 循环引用:如果对象中存在循环引用,例如对象 A 引用了对象 B,而对象 B 又引用了对象 A,那么 JSON.stringify() 将无法对这个对象进行序列化,会抛出 TypeError 错误。
  2. 函数和 symbol 属性:如果对象中包含函数或 symbol 属性,JSON.stringify() 将会将它们序列化为 undefined
  3. UndefinedNaN 值:如果对象中包含 undefinedNaN 值,JSON.stringify() 会将它们序列化为 null
  4. Date 对象:如果对象中包含 Date 对象,JSON.stringify() 会将其序列化为 ISO 格式的字符串(同 Date.toISOString())。
  5. RegExp 对象:如果对象中包含 RegExp 对象,JSON.stringify() 会将其序列化为空对象。
  6. 不可枚举属性:如果对象中包含不可枚举属性,例如通过 Object.defineProperty() 定义的属性,JSON.stringify() 将会将其忽略。它使用了与 Object.keys() 相同的算法访问属性,不可枚举的属性会被忽略。这意味着 MapSetWeakMapWeakSetRegExpArrayBuffer 等内置类型,序列化之后会变成空对象 {}