使用 ES12 中的 Object.getOwnPropertyDescriptors 方法对对象进行深度拷贝

阅读时长 6 分钟读完

引言

在日常的前端开发中,我们经常会遇到需要将一个对象进行深度拷贝的情况。一般情况下,我们使用常规的方法进行拷贝,比如使用 Object.assign() 或者使用 JSON.parse(JSON.stringify(obj))。这些方法虽然能够实现浅拷贝或深拷贝的功能,但对于一些复杂的对象,可能会存在一些问题,比如拷贝后的对象和原对象引用了同一个对象引用,修改其中一个对象的属性会影响到另一个对象,这就会导致一些不可预知的问题。

在 ES12 中,新增了一个 Object.getOwnPropertyDescriptors() 方法,该方法能够返回对象自身属性的描述符,包括 valuewritableenumerableconfigurable。那么,本文将介绍如何使用该方法来实现对象的深度拷贝。

深度拷贝对象的问题

在深度拷贝对象时,往往会出现对象引用相同的情况。例如,下面代码创建了一个对象 person1

现在我们想要通过深度拷贝的方式来创建一个对象 person2,并修改其中一个对象的属性值:

这时,我们会发现 person1address.city 也被修改了,这就是因为两个对象的 address 属性引用同一个对象引用的缘故。这时候,我们可能需要使用赋值运算符或者 Object.assign() 来解决该问题。

但是使用这些方法时,我们又会发现它们只能实现浅拷贝,即只能拷贝对象自身的属性,而不能拷贝对象的嵌套属性。

使用 Object.getOwnPropertyDescriptors 进行深度拷贝

在 ES12 中,新增了一个 Object.getOwnPropertyDescriptors 方法,该方法能够返回对象自身属性的描述符,包括 valuewritableenumerableconfigurable。我们可以利用这个方法,来实现对对象进行深度拷贝。

下面是一个使用 Object.getOwnPropertyDescriptors() 方法深度拷贝对象的示例:

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

上面的代码中,我们首先定义了一个 deepCopy 函数,该函数接收一个对象作为参数。函数内部使用 Object.keys() 方法获取对象自身的全部属性,然后使用 Object.getOwnPropertyDescriptor() 方法获取每个属性的描述符。这里使用了一个递归的方式,来对属性值为对象的属性进行拷贝。

一个比较复杂的示例:

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

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

输出的结果:

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

从输出结果可以看到,newBookbook 的属性值已经完全独立了。

结论

使用 Object.getOwnPropertyDescriptors() 方法能够实现对对象的深度拷贝,避免了一些对象引用同一个对象引用的问题。这种方法的优点是能够拷贝对象自身的所有属性,以及嵌套属性的值。对于一些较为复杂的对象,这种方法更为有效。

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

纠错
反馈