ECMAScript 2019 中的 Object.assign:对象的深浅拷贝

阅读时长 4 分钟读完

在前端开发中,经常需要对对象进行拷贝与合并。ECMAScript 2019中的Object.assign方法为我们提供了方便的对象拷贝与合并操作。在本文中,我们将深入探讨Object.assign的用法,并讨论对象的深浅拷贝问题。

了解Object.assign

Object.assign 方法用于将所有可枚举的属性,从一个或多个源对象复制到目标对象。该方法返回目标对象。示例代码如下:

上述示例中,我们将source对象中的b、c属性拷贝到了target对象中。需要注意的是,如果target对象中有与source对象同名的属性,则会覆盖掉原来的值。

除了基本类型的值属性外,Object.assign也可以拷贝引用类型的属性,如数组或对象。示例如下:

注意,该示例中,source对象的属性b也是一个对象,它和target对象的属性b指向的是同一个引用。因此,通过Object.assign拷贝属性b时,拷贝的是b引用的地址,而不是复制一个新的对象。

深拷贝与浅拷贝

在前面的例子中,我们演示了基本类型的属性值与引用类型的属性值的拷贝。但仅仅使用Object.assign仅仅是浅拷贝,也就是说只拷贝了引用,而没有拷贝引用指向的对象的内容。如果我们需要深拷贝一个对象,则需要借助其他的方法。

手写深拷贝函数

手写深拷贝函数的思路是,使用递归的方式遍历待拷贝的对象,当发现属性的值是引用类型时,再次调用深拷贝函数递归拷贝子对象。示例代码如下:

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

这里需要注意两个问题:

  1. 判断obj是否为对象或数组时,需要特判null,因为null的typeof值也是object。

  2. 在遍历对象属性时,需要通过Object.prototype.hasOwnProperty.call(obj, key)来判断该属性是否是对象自身的属性,而不是从原型继承而来的属性。

借助第三方库

如果你不想为了深拷贝而手写一个函数,也可以考虑使用一些第三方库来完成这个任务。例如,lodash中的_.cloneDeep方法可以帮助我们完成对象的深拷贝操作。示例代码如下:

需要注意的是,在使用这些库时,需要小心避免出现安全问题。因为对于拷贝一些特别大的、复杂的对象时,这些拷贝操作可能会耗费大量的CPU和内存资源,甚至会导致服务崩溃。

总结

在ECMAScript 2019中,我们可以使用Object.assign方法来拷贝对象属性。但是由于该方法只是浅拷贝,需要特别注意对象属性值为引用类型的情况。在拷贝引用类型的属性时,需要使用深拷贝。深拷贝可以手写一个函数实现,也可以使用第三方库。在实际的开发中,需要谨慎使用这些方法,防止出现性能和安全问题。

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

纠错
反馈