Skip to content

JSON.stringify的其他用法

跳过的的属性

  • 函数
  • Symbol 类型的键和值
  • 值为 undefined 的属性

注意,规避循环引用

md
let room = {
  number: 23
};

let meetup = {
  title: "Conference",
  participants: ["Tom", "Jerry"]
};

meetup.place = room;       // meetup 引用了 room
room.occupiedBy = meetup; // room 引用了 meetup

JSON.stringify(meetup); //会报错Uncaught TypeError: Converting circular structure to JSON

使用 replacer

JSON.stringify 的完整语法是:

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

replacer为要编码性数组或函数,space为缩进空格数。

  • 如果是函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换、处理;
  • 如果是数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中
md
let room = {
  number: 23
};

let meetup = {
  title: "Conference",
  participants: [{name: "John"}, {name: "Alice"}],
  place: room // meetup 引用了 room
};

room.occupiedBy = meetup; // room 引用了 meetup

JSON.stringify(meetup, ['title', 'participants'])
//输出 -> {"title":"Conference","participants":[{},{}]}

JSON.stringify(meetup, ['title', 'participants', 'place', 'name', 'number'])
//输出 -> {"title":"Conference","participants":[{"name":"John"},{"name":"Alice"}],"place":{"number":23}}

replacer为函数的情况,接受两个参数 key、value,分别对应每个对象的键值。

md
function replacer(key, value) {
  if (typeof value === "string") {
    return undefined;
  }
  return value;
}
function replacerFunc(key, value) {
  if (typeof value === "string") {
    return () => {};
  }
  return value;
}
const foo = {foundation: "Mozilla", model: "box", week: 45, transport: "car", month: 7};
JSON.stringify(foo, replacer);
// 输出-> {"week":45,"month":7}

请注意 replacer 函数会获取每个键/值对,包括嵌套对象和数组项。它被递归调用。replacer 中的 this 的值是包含当前属性的对象。

非预期效果

如果对象中包含非静态数据,如 new Date,会被内置的 toJSON 方法处理,返回这种类型的字符串。那如果对象中添加一个自定义的 toJSON,看会发生什么?

md
let room = {
  number: 23,
  position: {
    x: 10,
    y: 20
  },
  toJSON() {
    return this.number;
  }
};
JSON.stringify(room)

//输出 -> 23

也就是如果有 toJSON() 方法,toJSON() 方法返回什么值,序列化结果就返回什么值,其余的会被忽略。

特殊属性

stringify的过程对类型的处理不太一样,布尔值、数字、字符串的包装对象会被转换为原始值。 NaN、Infinity、null都会被转换为 null。

陕ICP备15010740号