ES12中的 Object.assign 方法:避免深拷贝对象时的问题

阅读时长 5 分钟读完

前言

在前端开发中,我们常常需要对对象进行复制、操作和拷贝。在 JavaScript 中,一般情况下,我们使用 Object.assign 方法来对对象进行浅拷贝。但是,当我们需要对多层嵌套的对象进行深拷贝时,会遇到很多问题。ES12 中的 Object.assign 方法提供了一种新的解决方案,让我们更方便地进行操作。

什么是深拷贝?

深拷贝是指复制一个对象,使得新对象与原对象在内存中不共享任何地址空间。当我们修改新对象时,不会影响原对象。

JavaScript 中,对象分为两种类型:基本类型和引用类型。

基本类型,如数字、字符串、布尔值等,存储在栈上,可以直接复制。

引用类型,如数组、对象等,存储在堆上,不能直接复制。复制后,新对象与原对象会共享同一块堆空间,因此修改新对象也会影响原对象。

为什么需要深拷贝?

在开发中,我们常常需要对对象进行值的复制和操作。如果直接复制一个对象,会出现多个变量引用同一个对象的情况,当其中一个变量更改了对象的属性,其他变量的对象属性也会跟着改变。这种情况下,我们需要对对象进行深拷贝。

浅拷贝

在 JavaScript 中,使用 Object.assign() 方法来对对象进行浅拷贝。

-- -------------------- ---- -------
----- ------- - -
  -- --
  -- --
  -- -
    -- --
    -- -
  -
--

----- ------- - ----------------- ---------

----------- - --

------------------------- -- ------- -

在上面的示例中,我们使用 Object.assign() 方法将 object1 复制到 object2,然后将 object2c.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.cobj2.b.c,发现 obj1.b.c 的值仍为 2,而 obj2.b.c 的值已经被修改为 20

用递归函数来进行深拷贝

除了可以使用 Object.assign() 方法进行深拷贝外,我们还可以使用递归函数来进行拷贝操作。

-- -------------------- ---- -------
-------- -------------- -
  --- ------ - ------------------ - -- - ---
  --- ---- --- -- ---- -
    -- ------------------------------------------ ----- -
      -- ------- -------- --- -------- -- -------- --- ----- -
        ----------- - --------------------
      - ---- -
        ----------- - ---------
      -
    -
  -
  ------ -------
-

----- ---- - -
  -- --
  -- -
    -- --
    -- -
  -
--

----- ---- - ----------------

---------------------- -- ------- -
-------- - ---
---------------------- -- ------- -
---------------------- -- ------- --

在这个示例中,我们使用一个递归函数 deepClone 来进行深拷贝操作。首先判断传入的对象是否为数组,如果是,则创建一个空数组,并遍历原数组中的元素,递归调用 deepClone 并存储到新数组中。如果传入的对象不是数组,则创建一个空对象,并遍历原对象中的属性,递归调用 deepClone 并存储到新对象中。最后返回新对象。

总结

文中,我们介绍了深拷贝的概念和原因,以及如何用 Object.assign() 方法和递归函数进行深拷贝操作。在实践中,我们应该根据需求选择合适的方法,以减少代码的复杂度和提高代码的性能。

参考资料

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/647bd92a968c7c53b072159b

纠错
反馈