本文结合了自己的理解进行了意译,如有需要,可查看原文,附址:javascript.plainenglish.io/never-use-j…
使用JSON.stringify()深度克隆有很多陷阱。
当对象中有时间类型的元素时 —— Date将会被转化成string类型的数据
const obj ={
date: new Date()
}
typeof obj.date === 'object' // true
const objCopy = JSON.parse(JSON.stringify(obj))
typeof objCopy.date === 'string' // true
然后你会惊喜的发现getTime()无法使用,getYearFull()也不行。Date的所有内置方法都无法使用。然而,String的所有内置方式都可以调用。
当对象中有undefined或Function的数据时 —— undefined和Function会直接丢失
const obj = {
undef: undefined,
fun: () => { console.log('Programmer Ahui, aba aba') }
}
console.log(obj, "obj");
const objCopy = JSON.parse(JSON.stringify(obj));
console.log(objCopy, "objCopy") // {}
打印输出后,你将看到这两种类型的数据都消失了(没有这个属性值了)。
对象中有NaN、Infinity和-Infinity的值在序列化后将会被转成null
1.7976931348623157E+10308是浮点数的最大值,表示为无穷大 -1.7976931348623157E+10308是浮点数的最小值,表示为负无穷大
const obj = {
nan: NaN,
infinityMax:1.7976931348623157E+10308,
infinityMin:-1.7976931348623157E+10308,
}
console.log(obj, "obj");
const objCopy = JSON.parse(JSON.stringify(obj));
console.log(objCopy, "objCopy") // obj = {nan: null, infinityMax: null, infinityMin: null }
当循环使用对象时将会报错。
如果你足够“幸运”需要复制下面这些对象:
const obj = {
nan:NaN,
infinityMax:1.7976931348623157E+10308,
infinityMin:-1.7976931348623157E+10308,
undef: undefined,
fun: () => { console.log('Programmer Ahui, Aba Aba') },
date:new Date,
}
// 结果是 obj={}
然后你会发现所有的数据都无法使用了。
所以你还会继续使用JSON.stringify()去实现深度克隆吗?
如果还是要这么做的话,那要注意了。作者建议在将来的深度克隆中使用递归方式进行深度复制。
总结
- 当对象中有Date数据时,序列化后会变成String格式
- 当对象中有undefined和Function数据时,序列化后会直接丢失
- 如果对象中有NaN,Infinity,-Infinity,序列化后会显示成null