JSON.stringify()
用法:JSON.stringify(value, [replacer], [space])
第一个参数:
value: 必选,将要序列后成 JSON 字符串的值。
第二个参数:
replacer: 可选
- 如果是一个
函数
,则在序列化过程中,属性进行转换或处理。如果函数返回值为undefined 或者 函数时,该属性就会被过滤掉;- 如果是一个
数组
,那么只包含在这个数组中的属性名才会被序列化- 如果该参数为 null 或者未提供,则对象所有的属性都会被序列化。
// 函数
const obj = { a: '1', b: 2, c: '3'};
const objStr = JSON.stringify(obj, (key, value) => {
if(typeof value === 'string') return undefined;
return value;
})
console.log(objStr); // '{"b":2}'
// 数组
const obj = { a: '1', b: 2, c: '3'};
const objStr = JSON.stringify(obj, [ 'a', 'b'])
console.log(objStr); // '{"a":"1","b":2}'
第三个参数
space:可选,用于指定缩进的空白字符串,作用于美化输出
const obj = { a: '1', b: 2, c: '3'};
// 1. 如果该参数没有提供(或者为 null),将没有空格。
const objStr1 = JSON.stringify(obj, [ 'a', 'b'])
console.log(objStr1);
// 2. 如果是数字,它代表多少个空格;上限为10,若小于1则表示没有空格
const objStr2 = JSON.stringify(obj, [ 'a', 'b'], 5)
console.log(objStr2);
// 3. 如果是字符串,就在每行输出值的时候把这些字符串附加上去。最大长度也是10个字符
const objStr3 = JSON.stringify(obj, [ 'a', 'b'], 'uu')
console.log(objStr3);
// 4. 如果是一些转义字符,比如“\t”,表示回车,那么它每行一个回车
const objStr4 = JSON.stringify(obj, [ 'a', 'b'], '\t')
console.log(objStr4);
特性
1. toJSON() 方法
转换值如果有 toJSON() 方法,toJSON() 方法返回什么值,
序列化结果就返回什么值,其余值会被忽略。
const obj = {
a: 1,
toJSON() {
return '11'
}
}
console.log(JSON.stringify(obj)) // "11"
2. 布尔值、数字、字符串的包装对象
布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值
console.log(JSON.stringify([new Number(1), new String("1"), new Boolean(true)]))
// [1,"1",true]
3. 非数组对象
非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中。
4. undefined、任意的函数以及 symbol 值
- 出现在对象属性值中: undefined、任意函数、Symbol 值在序列化过程中将会被
忽略
- 出现在数组中: undefined、任意函数、Symbol值会被转化为
null
- 单独转换时: 会返回
undefined
const obj = {
a() {},
b: undefined,
c: 1,
b: Symbol(1)
};
const strObj = JSON.stringify(obj);
console.log(strObj); // '{"c":1}'
const arr = [undefined, 1, function a(){}, Symbol(1) ];
const strArr = JSON.stringify(arr);
console.log(strArr); // '[null,1,null,null]'
const str1 = JSON.stringify(undefined);
console.log(str1) // undefined
const str2 = JSON.stringify(function a() {});
console.log(str2) // undefined
const str3 = JSON.stringify(Symbol(1));
console.log(str3) // undefined
5. 循环引用
对包含循环引用的对象(对象之间相互引用,形成无限循环)执行此方法,会抛出错误。
const obj1 = {a: '1'};
const obj2 = {obj : obj1};
obj1.c = obj2;
JSON.stringify(obj1) // 报错
6. Symbol
以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们。
const obj = {
a: '1',
[Symbol('b')]: true,
}
function replacer(key, value) {
if (typeof key === "symbol") return value;
}
console.log(JSON.stringify(obj)) // {"a":"1"}
7. Date对象
Date对象上部署了
toJSON
方法(同Date.toISOString()
), 因此会被当做字符串处理。
console.log(JSON.stringify(new Date())); // "2022-11-21T07:05:24.919Z"
8. NaN Infinity null
NaN Infinity null 此三类数值序列化过程中会被当作
null
const str = JSON.stringify([Number('123a'), +'123a', 1/0]
console.log(str); // "[null,null,null]"
9. 可枚举属性
其他类型的对象,包括 Map/Set/WeakMap/WeakSet,仅会序列化可枚举的属性。
const obj = {};
Object.defineProperties(obj, {
'a': {
value: '1',
enumerable: true,
},
'b': {
value: '2',
enumerable: false,
}
})
console.log(JSON.stringify(obj)) // {"a":"1"}
JSON.parse()
用法:JSON.parse(text, [reviver])
第一个参数:
text: 必需,一个有效的 JSON 字符串。
(不允许用逗号作为结尾)
第二个参数:
reviver:可选,转换结果的函数, 将为对象的每个成员调用此函数。函数的遍历顺序依照:从最内层开始,按照层级顺序,依次向外遍历
const objStr = '{"a":1,"b": {"c": 2}}';
const obj = JSON.parse(objStr, function(key, value) {
console.log(key); // 'a' 'c' 'b' ''
});