前言
在前端开发中,我们常常需要对对象进行复制、操作和拷贝。在 JavaScript 中,一般情况下,我们使用 Object.assign
方法来对对象进行浅拷贝。但是,当我们需要对多层嵌套的对象进行深拷贝时,会遇到很多问题。ES12 中的 Object.assign
方法提供了一种新的解决方案,让我们更方便地进行操作。
什么是深拷贝?
深拷贝是指复制一个对象,使得新对象与原对象在内存中不共享任何地址空间。当我们修改新对象时,不会影响原对象。
JavaScript 中,对象分为两种类型:基本类型和引用类型。
基本类型,如数字、字符串、布尔值等,存储在栈上,可以直接复制。
引用类型,如数组、对象等,存储在堆上,不能直接复制。复制后,新对象与原对象会共享同一块堆空间,因此修改新对象也会影响原对象。
为什么需要深拷贝?
在开发中,我们常常需要对对象进行值的复制和操作。如果直接复制一个对象,会出现多个变量引用同一个对象的情况,当其中一个变量更改了对象的属性,其他变量的对象属性也会跟着改变。这种情况下,我们需要对对象进行深拷贝。
浅拷贝
在 JavaScript 中,使用 Object.assign()
方法来对对象进行浅拷贝。
-- -------------------- ---- ------- ----- ------- - - -- -- -- -- -- - -- -- -- - - -- ----- ------- - ----------------- --------- ----------- - -- ------------------------- -- ------- -
在上面的示例中,我们使用 Object.assign()
方法将 object1
复制到 object2
,然后将 object2
的 c.d
修改为 5
。这时再输出 object1.c.d
,其值为 5
,即原对象被修改。
这是因为 Object.assign()
方法只是将对象的属性值复制到新对象,而对象的属性值如果是一个对象,则复制的是该对象的地址,从而导致新对象和原对象共享同一个根对象。
深拷贝
JavaScript 中,有多种深拷贝的方法,例如遍历原对象并递归复制,使用 JSON 序列化和反序列化等。但这些方法都存在一些问题和限制。
使用 Object.assign
方法进行深拷贝
ES12 中的 Object.assign()
方法提供了一种新的解决方案,可以照顾到多层嵌套对象的情况,使得我们更方便地进行操作。
-- -------------------- ---- ------- ----- ---- - - -- -- -- - -- -- -- - - -- ----- ---- - ----------------- ----- - -- ----------------- ------- --- ---------------------- -- ------- - -------- - --- ---------------------- -- ------- - ---------------------- -- ------- --
在上面的示例中,我们使用 Object.assign()
方法进行深拷贝。首先使用 Object.assign()
方法将 obj1
复制到 obj2
,然后使用 Object.assign()
方法将 obj1.b
复制到 obj2.b
。因为 Object.assign()
方法仅仅复制对象的属性值,所以这时 obj2.b
不再引用原对象 obj1.b
,而是复制了一份。
我们修改 obj2.b.c
的值为 20
,输出 obj1.b.c
和 obj2.b.c
,发现 obj1.b.c
的值仍为 2
,而 obj2.b.c
的值已经被修改为 20
。
用递归函数来进行深拷贝
除了可以使用 Object.assign()
方法进行深拷贝外,我们还可以使用递归函数来进行拷贝操作。
-- -------------------- ---- ------- -------- -------------- - --- ------ - ------------------ - -- - --- --- ---- --- -- ---- - -- ------------------------------------------ ----- - -- ------- -------- --- -------- -- -------- --- ----- - ----------- - -------------------- - ---- - ----------- - --------- - - - ------ ------- - ----- ---- - - -- -- -- - -- -- -- - - -- ----- ---- - ---------------- ---------------------- -- ------- - -------- - --- ---------------------- -- ------- - ---------------------- -- ------- --
在这个示例中,我们使用一个递归函数 deepClone
来进行深拷贝操作。首先判断传入的对象是否为数组,如果是,则创建一个空数组,并遍历原数组中的元素,递归调用 deepClone
并存储到新数组中。如果传入的对象不是数组,则创建一个空对象,并遍历原对象中的属性,递归调用 deepClone
并存储到新对象中。最后返回新对象。
总结
文中,我们介绍了深拷贝的概念和原因,以及如何用 Object.assign()
方法和递归函数进行深拷贝操作。在实践中,我们应该根据需求选择合适的方法,以减少代码的复杂度和提高代码的性能。
参考资料
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/647bd92a968c7c53b072159b