一、JSON.stringify 的详细介绍
在 JavaScript 中,JSON.stringify是一个非常重要的函数,它用于将 JavaScript 值转换为 JSON 字符串。其语法为JSON.stringify(value[, replacer [, space]])。
参数解释:
value:这是将要被序列化成一个 JSON 字符串的值。它可以是任何有效的 JavaScript 对象、数组、字符串、数字、布尔值等。
replacer:这个参数具有多种用途。如果它是一个函数,那么在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理。该函数接收两个参数,分别是属性名(key)和属性值(value)。如果replacer是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中。如果replacer为null或者未提供,则对象所有的属性都会被序列化。
space:该参数用于指定缩进用的空白字符串,起到美化输出的作用。
举例说明:
如下代码展示了JSON.stringify的不同用法。
首先定义一个对象obj:
const obj = {
a: 'a',
b: 'b',
c: {
d: 'd'
}
};
简单使用:
当直接调用JSON.stringify(obj)时,会将对象obj序列化为 JSON 字符串,输出结果为{"a":"a","b":"b","c":{"d":"d"}}。
传入replacer为函数:
当传入第二个参数为一个函数时,被序列化的每个属性都会经过这个函数的转化。在下面的例子中,函数对属性值进行了判断,如果值为'a',则将其改为'A',然后返回处理后的结果。
console.log(
JSON.stringify(obj, (key, value) => {
if (value === 'a') {
return 'A';
}
return value;
})
);
// {"a":"A","b":"b","c":{"d":"d"}}
传入replacer为数组:
当传入第二个参数为一个数组时,只有在这个数组中的属性名才会被返回。在下面的例子中,数组包含'a'、'c'、'd',所以最终只有这些属性被序列化到 JSON 字符串中。
javascript
Copy
console.log(JSON.stringify(obj, ['a', 'c', 'd']));
// {"a":"a","c":{"d":"d"}}
传入space美化输出:
当传入第三个参数为两个空格时,会起到美化输出的作用,使生成的 JSON 字符串具有缩进,更加易读。
console.log(JSON.stringify(obj, null, ' '));
// {
// "a": "a",
// "b": "b",
// "c": {
// "d": "d"
// }
// }
安全问题:
数据丢失:
Date 对象拷贝后变成字符串:如果对象中包含Date对象,在使用JSON.stringify进行序列化后,Date对象会变成字符串。例如:
const obj = {
a: new Date()
};
console.log(JSON.stringify(obj));
// {"a":"2022-04-01T08:40:48.781Z"}
正则、Error 对象拷贝后变成空对象:如果对象中包含正则表达式对象或Error对象,序列化后会变成空对象。例如:
const obj = {
a: /[123]/g,
b: new Error('err')
};
console.log(JSON.stringify(obj));
// {"a":{},"b":{}}
函数、undefined 属性、Symbol 属性拷贝后属性丢失:如果对象中包含函数、undefined属性或Symbol属性,在序列化后这些属性会丢失。例如:
const obj = {
a: console.log,
b: undefined,
c: Symbol('123')
};
console.log(JSON.stringify(obj));
// {}
NaN、Infinity、-Infinity 拷贝后变成 null:如果对象中包含NaN、Infinity或-Infinity,在序列化后会变成null。例如:
const obj = {
a: NaN,
b: Infinity,
c: -Infinity
};
console.log(JSON.stringify(obj));
// {"a":null,"b":null,"c":null}
改变对象的原型链:使用JSON.stringify和JSON.parse进行序列化和反序列化操作可能会改变对象的原型链。例如:
function A() {
this.a = 'a';
}
const a = new A();
const b = JSON.parse(JSON.stringify(a));
console.log(a.constructor, b.constructor);
// [Function: A] [Function: Object]
循环引用报错:如果对象中存在循环引用,即对象之间相互引用,那么在使用JSON.stringify时会抛出TypeError错误。例如:
const a = {
a: 'a'
};
const b = {
b: 'b'
};
a.next = b;
b.pre = a;
console.log(JSON.parse(JSON.stringify(a)));
// TypeError: Converting circular structure to JSON
二、JSON.parse 的详细介绍
JSON.parse是用于将 JSON 字符串解析为 JavaScript 值的函数。其语法为JSON.parse(text[, reviver])。
参数解释:
text:要被解析成 JavaScript 值的字符串。这个字符串必须是符合 JSON 格式的。
reviver:这是一个转换器函数。如果传入该函数,可以用来修改解析生成的原始值,调用时机在parse函数返回之前。
举例说明:
首先定义一个 JSON 格式的字符串str:
const str = '{"a":1,"b":2,"c":3}';
简单使用:
当直接调用JSON.parse(str)时,会将字符串解析为一个 JavaScript 对象,输出结果为{ a: 1, b: 2, c: 3 }。
传入reviver处理value:
当传入第二个参数为一个函数时,在解析过程中,每个属性值都会经过这个函数的处理,处理完后再返回。在下面的例子中,函数将每个属性值乘以 2。
console.log(
JSON.parse(str, (key, value) => {
if (key === '') return value;
return 2 * value;
})
);
//{ a: 2, b: 4, c: 6 }