不要使用JSON.stringify()进行深度克隆,这里有陷阱

242 阅读1分钟

本文结合了自己的理解进行了意译,如有需要,可查看原文,附址: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()去实现深度克隆吗?

如果还是要这么做的话,那要注意了。作者建议在将来的深度克隆中使用递归方式进行深度复制。

总结

  1. 当对象中有Date数据时,序列化后会变成String格式
  2. 当对象中有undefined和Function数据时,序列化后会直接丢失
  3. 如果对象中有NaN,Infinity,-Infinity,序列化后会显示成null