背景
很多同学可能只知道JSON.stringify是将数据序列化,变为JSON字符串的,但不知其有很多坑,也不知其还有两外两个参数
本文目的
1,JSON.stringify作用
2,JSON.stringify6种问题
3,JSON.stringify方法三个参数
JSON.stringify作用
先说一下JSON.stringify() 方法作用:用于将 JavaScript 值转换为 JSON 字符串。
正文
JSON.stringify问题清单
1,Date 日期调用了 toJSON() 将其转换为了 string 字符串。
2,对象中有undefined和Function类型数据的时候,序列化之后会直接丢失。
3,对象中有NaN、Infinity和-Infinity的时候,序列化之后会显示null。
4,对象循环引用的时候,会直接报错。
5,以 symbol 为属性键的属性都会被完全忽略掉
6,只可序列化可枚举的属性
下面我们依次来讲清楚这6个问题
1,Date 日期调用了 toJSON() 将其转换为了 string 字符串
const obj = {
date:new Date()
}
typeof obj.date // object
const objCopy = JSON.parse(JSON.stringify(obj));
console.log(objCopy.date) // 2022-07-16T08:47:13.753Z
然后关于Date对象的方法都会用不了,getTime、getMonth等啥都没了,因为已经变为了字符串。
2,对象中有undefined和Function类型数据的时候,序列化之后会直接丢失
不多说,直接上代码
const obj = {
name: undefined,
sayName: () => { console.log('hhh') }
}
const objCopy = JSON.parse(JSON.stringify(obj));
console.log('objCopy:', objCopy) // {}
这里是浏览器运行截图
3,对象中有NaN、Infinity和-Infinity的时候,序列化之后会显示null
老规矩,看代码
const obj = {
NaN:NaN,
InfinityMax:Infinity,
InfinityMin:-Infinity,
}
console.log(obj, "obj"); // {NaN: NaN, InfinityMax: Infinity, InfinityMin: -Infinity} 'obj'
const objCopy = JSON.parse(JSON.stringify(obj));
console.log(objCopy,"objCopy") // {NaN: null, InfinityMax: null, InfinityMin: null} 'objCopy'
浏览器运行截图
怎么样,是不是已经难以想象有这么严重的问题了
4,对象循环引用的时候,会直接报错
const obj = {}
obj.aaa = obj;
const objCopy = JSON.parse(JSON.stringify(obj)); // 这里直接报错:Uncaught TypeError: Converting circular structure to JSON--> starting at object with constructor 'Object'--- property 'aaa' closes the circleat JSON.stringify
console.log("objCopy:", objCopy)
下面时报错截图
5,以 symbol 为属性键的属性都会被完全忽略掉,即便 replacer 参数中强制指定包含了它们
JSON.stringify({[Symbol("foo")]: "foo"}); // '{}'
JSON.stringify(
{[Symbol.for("foo")]: "foo"},
function (k, v) {
if (typeof k === "symbol"){
return "a symbol";
}
}
); // undefined
6,只可序列化可枚举的属性,包括 Map/Set/WeakMap/WeakSet
// 不可枚举的属性默认会被忽略:
JSON.stringify(
Object.create(
null,
{
x: { value: 'x', enumerable: false },
y: { value: 'y', enumerable: true }
}
)
);
// "{"y":"y"}"
现在大家对JSON.stringify的几个问题应该都清楚了吧
JSON.stringify3个参数
JSON.stringify(value, ?replacer, ?space)
1,value:将要序列化成 一个 JSON 字符串的值。
2,?replacer:?代表可选,如果该参数是一个函数,则在序列化过程中,被序列化的值的每个属性都会经过该函数的转换和处理;如果该参数是一个数组,则只有包含在这个数组中的属性名才会被序列化到最终的 JSON 字符串中;如果该参数为 null 或者未提供,则对象所有的属性都会被序列化。
3,?space:指定缩进用的空白字符串,用于美化输出(pretty-print);如果参数是个数字,它代表有多少的空格;上限为 10。该值若小于 1,则意味着没有空格;如果该参数为字符串(当字符串长度超过 10 个字母,取其前 10 个字母),该字符串将被作为空格;如果该参数没有提供(或者为 null),将没有空格。
const obj = {
name:"aaa",
age: 18
}
第二个参数?replace
?replace为数组时
?replace为函数时
?replace为函数时,所有属性都会经过此函数的过滤
第三个参数?space
此参数时为了美化输出,有两种使用方式,数字或者字符