JS深拷贝

146 阅读2分钟

JS深拷贝是指创建一个新对象,该对象与原始对象具有相同的属性和值,但是两个对象不共享相同的内存地址。这意味着如果您更改新对象中的任何属性,原始对象不会受到影响,反之亦然。

以下是一个使用递归方法实现JS深拷贝的示例代码:

 function deepClone(obj) {
  //判断传参不是对象或者数组直接返回本身
  if (obj === null || typeof obj !== "object") {
    return obj;
  }
  // 判断对象是否为数组,若 是 则 clone为空数组,反之则clone是空对象
  let clone = Array.isArray(obj) ? [] : {};

  //便利obj的属性
  for (let key in obj) {
    //判断是否为obj自身属性
    if (obj.hasOwnProperty(key)) {
      //拷贝obj的key给clone
      clone[key] = deepClone(obj[key]);
    }
  }

  return clone;
}

此函数首先检查该对象是否为null或非对象。如果是,则返回原始对象本身。否则,它会创建一个新的空对象或数组,具体取决于原始对象的类型。

然后,函数使用for循环遍历原始对象的所有属性,并使用递归方法将每个属性值深拷贝到新对象中。递归方法的调用确保了每个嵌套对象都被正确地深拷贝。

最后,函数返回新对象,其中包含原始对象的所有属性和值,但不共享内存地址。

使用该函数进行深拷贝的示例代码如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      let obj1 = {
        name: "John",
        age: 30,
        hobbies: ["reading", "traveling"],
        address: {
          street: "123 Main St",
          city: "Anytown",
          state: "CA",
        },
      };

      let obj2 = deepClone(obj1);

      console.log(obj1); // { name: 'John', age: 30, hobbies: [ 'reading', 'traveling' ], address: { street: '123 Main St', city: 'Anytown', state: 'CA' } }
      console.log(obj2); // { name: 'John', age: 30, hobbies: [ 'reading', 'traveling' ], address: { street: '123 Main St', city: 'Anytown', state: 'CA' } }

      // Changing a property in obj2 does not affect obj1
      obj2.age = 40;
      obj2.hobbies.push("swimming");
      obj2.address.city = "Othertown";

      console.log(obj1); // { name: 'John', age: 30, hobbies: [ 'reading', 'traveling' ], address: { street: '123 Main St', city: 'Anytown', state: 'CA' } }
      console.log(obj2); // { name: 'John', age: 40, hobbies: [ 'reading', 'traveling', 'swimming' ], address: { street: '123 Main St', city: 'Othertown', state: 'CA' } }
    </script>
  </body>
</html>

在这个例子中,我们首先定义了一个名为obj1的对象,它包含字符串、数字、数组和嵌套对象等多种类型的属性。然后,我们使用deepClone函数创建了一个名为obj2的新对象,并将obj1的值深拷贝到obj2中。

接下来,我们更改了obj2的一些属性,包括年龄、兴趣爱好和地址城市。由于obj1和obj2不共享内存地址,因此这些更改不会影响obj1的值。因此,当我们打印obj1和obj2时,它们的值是不同的。

总之,JS深拷贝是一种非常有用的技术,可以确保您的代码在处理对象和嵌套对象时不会出现问题。使用递归方法实现JS深拷贝是一种常见的方法,但也可以使用其他技术,例如序列化和反序列化JSON对象。