将一个 JavaScript 对象或值转换为 JSON 字符串。如果指定了一个 replacer 函数,则可以选择性地替换值,或者指定的 replacer 是数组,则可选择性地仅包含数组指定的属性。
参数一:JSON 值
将要序列化成 一个 JSON 字符串的值,在转换时需要注意如下事项:
1.转换值包含 toJSON
方法
如果一个被序列化的对象拥有 toJSON 方法,那么该 toJSON 方法就会覆盖该对象默认的序列化行为:不是该对象被序列化,而是调用 toJSON 方法后的返回值会被序列化,例如:
var obj = {
foo: "foo",
toJSON: function () {
return "bar";
},
};
JSON.stringify(obj); // '"bar"'
JSON.stringify({ x: obj }); // '{"x":"bar"}'
toJSON
的正确用法应该是,返回一个能够被字符串化的安全的 JSON 值。
2.布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值
// "[3,\"false\",false]"
JSON.stringify([new Number(3), new String("false"), new Boolean(false)]);
3.undefined、任意的函数以及 symbol 值,在序列化过程中会被忽略或者被转换成 null
出现在非数组对象的属性值中,就会被忽略,其中 Symbol 无论出现在键或值都会被忽略:
const object = {
[Symbol("foo")]: "foo",
foo: Symbol(100),
boo: function () {},
bof: undefined,
};
JSON.stringify(object); // "{}"
出现在数组中,会被转换为 null,另外 NaN, Infinity 等数值也会被转为 null
const array1 = [Symbol("foo"), function () {}, undefined, NaN, Infinity];
JSON.stringify(array); // "[null,null,null,null,null]"
4.对包含循环引用的对象(对象之间相互引用,形成无限循环)执行此方法,会抛出错误。
5.非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中。
6.其他类型的对象,包括 Map/Set/WeakMap/WeakSet,仅会序列化可枚举的属性,不可枚举的属性默认会被忽略:
JSON.stringify(
Object.create(null, {
x: { value: "x", enumerable: false },
y: { value: "y", enumerable: true },
})
);
// "{\"y\":\"y\"}"
7.Date 日期调用了 toJSON() 将其转换为了 string 字符串(同 Date.toISOString()),因此会被当做字符串处理。
// "\"2006-01-02T15:04:05.000Z\""
console.log(JSON.stringify(new Date(2006, 0, 2, 15, 4, 5)));
参数二:replacer(可选)
1.replacer 作为函数
replacer 作为函数,在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理。它有两个参数,键(key)和值(value),它们都会被序列化。
在开始时, replacer 函数会被传入一个空字符串作为 key 值,代表着要被 stringify 的这个对象。随后每个对象或数组上的属性会被依次传入。
function replacer(key, value) {
if (typeof value === "string") {
return undefined;
}
return value;
}
var foo = {
foundation: "Mozilla",
model: "box",
week: 45,
transport: "car",
month: 7,
};
var jsonString = JSON.stringify(foo, replacer); // {"week":45,"month":7}
2.replacer 作为数组
replacer 作为数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中;
var foo = {
foundation: "Mozilla",
model: "box",
week: 45,
transport: "car",
month: 7,
};
JSON.stringify(foo, ["week", "month"]);
// '{"week":45,"month":7}', 只保留 “week” 和 “month” 属性值。
3.replacer 未提供或为 null
如果该参数为 null 或者未提供,则对象所有的属性都会被序列化。
参数三:space(可选)
指定缩进用的空白字符串,用于美化输出(pretty-print);
JSON.stringify({ uno: 1, dos: 2 }, null, "\t");
// '{ \
// "uno": 1, \
// "dos": 2 \
// }'
1.space 值是数字
如果参数是个数字,它代表有多少的空格;上限为 10。该值若小于 1,则意味着没有空格;在字符串化时每一级别会比上一级别缩进多这个数字值的空格。
2.space 值是字符串
如果该参数为字符串(当字符串长度超过 10 个字母,取其前 10 个字母),该字符串将被作为空格;每一级别会比上一级别多缩进该字符串。
3.space 未提供或为 null
如果该参数没有提供(或者为 null),将没有空格。