返回

JavaScript中的对象拷贝:浅拷贝与深拷贝揭秘

前端

在 JavaScript 的编程世界中,对象拷贝是一个司空见惯的操作。然而,在这看似简单的动作背后,却隐藏着两个截然不同的拷贝方式:浅拷贝与深拷贝。理解这两者的区别至关重要,因为它们对数据的处理方式有着天壤之别。

浅拷贝:表象的复制

浅拷贝仅仅复制对象的顶层属性。这意味着,如果一个对象包含其他对象或数组,则浅拷贝只会复制这些引用的内存地址,而不是真正复制这些引用的对象或数组。

const originalObject = {
  name: 'John',
  address: {
    street: 'Main Street',
    city: 'Anytown',
  },
};

const shallowCopy = Object.assign({}, originalObject);

// 修改浅拷贝的属性
shallowCopy.name = 'Jane';

// 查看原始对象,发现它的属性也发生了变化!
console.log(originalObject.name); // 'Jane'

如上例所示,当我们对浅拷贝中的 name 属性进行修改时,原始对象的 name 属性也随之改变。这是因为浅拷贝只是复制了 address 对象的引用,而不是复制其值。

深拷贝:彻底的克隆

深拷贝则完全不同。它不仅仅复制对象的顶层属性,还会递归地复制所有嵌套的对象和数组。这意味着,修改深拷贝的属性不会影响原始对象。

const originalObject = {
  name: 'John',
  address: {
    street: 'Main Street',
    city: 'Anytown',
  },
};

// 使用 lodash 库进行深拷贝
const deepCopy = _.cloneDeep(originalObject);

// 修改深拷贝的属性
deepCopy.name = 'Jane';

// 查看原始对象,发现它的属性保持不变
console.log(originalObject.name); // 'John'

在上面的例子中,即使我们对深拷贝的 name 属性进行了修改,原始对象的 name 属性仍然保持不变。这是因为深拷贝创建了一个完全独立的对象,它不与原始对象共享任何内存地址。

何时选择浅拷贝或深拷贝?

浅拷贝和深拷贝都各有其用途:

  • 浅拷贝: 适用于需要复制对象的基本结构的情况,而不必担心对嵌套对象或数组的修改。
  • 深拷贝: 适用于需要创建对象完全独立副本的情况,以防止修改副本对原始对象产生影响。