返回

剖析 JS 中的深浅拷贝难题

前端

正文

在 JavaScript 中,当我们想要复制一个对象或数组时,有两种选择:深拷贝和浅拷贝。

浅拷贝 只复制第一层属性和嵌套对象或数组的引用。这意味着如果一个对象或数组包含另一个对象或数组,则浅拷贝不会复制嵌套对象或数组的属性。

深拷贝 会递归地复制对象或数组的所有属性和嵌套对象或数组。这意味着如果一个对象或数组包含另一个对象或数组,则深拷贝会复制嵌套对象或数组的所有属性。

以下是对浅拷贝和深拷贝的进一步解释:

浅拷贝

  • 只复制对象或数组的第一层属性。
  • 不会复制嵌套对象或数组的属性。
  • 如果对象或数组包含另一个对象或数组,则只复制嵌套对象或数组的引用。
  • 使用==或===比较两个浅拷贝对象或数组时,可能不一致。
  • 使用浅拷贝可以节省内存空间,因为只复制了对象或数组的第一层属性。
  • 使用浅拷贝可以提高性能,因为只复制了对象或数组的第一层属性。

深拷贝

  • 会递归地复制对象或数组的所有属性。
  • 不仅复制了对象或数组的第一层属性,还会复制嵌套对象或数组的所有属性。
  • 如果对象或数组包含另一个对象或数组,则会递归地复制嵌套对象或数组的所有属性。
  • 使用==或===比较两个深拷贝对象或数组时,总是一致的。
  • 使用深拷贝会占用更多的内存空间,因为复制了对象或数组的所有属性。
  • 使用深拷贝可能会降低性能,因为复制了对象或数组的所有属性。

在某些情况下,深拷贝会比浅拷贝更好,但有时浅拷贝也足够了。例如,如果我们只想要复制对象或数组的第一层属性,那么浅拷贝就足够了。但是,如果我们想要复制对象或数组的所有属性,则需要使用深拷贝。

举个例子

var obj1 = {
  name: "John Doe",
  age: 30,
  address: {
    street: "123 Main Street",
    city: "Anytown, USA",
    state: "CA"
  }
};

var obj2 = _.cloneDeep(obj1);

obj2.name = "Jane Doe";

console.log(obj1.name); // "John Doe"
console.log(obj2.name); // "Jane Doe"

在这个例子中,我们使用 _.cloneDeep() 来深拷贝 obj1 对象。这会创建一个新的对象 obj2,该对象包含 obj1 的所有属性和嵌套对象。我们然后将 obj2.name 的值更改为 "Jane Doe"。当我们比较 obj1.nameobj2.name 时,我们会发现 obj1.name 的值仍然是 "John Doe",而 obj2.name 的值是 "Jane Doe"。这意味着深拷贝成功地复制了 obj1 对象的所有属性和嵌套对象。

总结

深拷贝和浅拷贝都是 JavaScript 中复制对象或数组的两种方法。深拷贝会递归地复制对象或数组的所有属性和嵌套对象或数组,而浅拷贝只复制第一层属性和嵌套对象或数组的引用。在某些情况下,深拷贝会比浅拷贝更好,但有时浅拷贝也足够了。