返回

浅拷贝和深拷贝的本质差异是什么?

前端

理解浅拷贝和深拷贝

在计算机科学领域,浅拷贝和深拷贝的概念至关重要。浅拷贝只复制对象本身,而深拷贝则复制对象及其所有属性和子对象。要理解这两者的区别,我们可以用一个形象的类比:

  • 浅拷贝就像复印机。当您使用复印机复印一张纸时,您得到的是原件的副本,但副本和原件是分开的两个独立实体。对副本的任何修改都不会影响原件。

  • 深拷贝就像克隆机。当您使用克隆机克隆一只绵羊时,您得到的是一只与原羊完全相同的新绵羊。新绵羊和原羊是两个独立的个体,但它们拥有相同的基因和特征。对新绵羊的任何修改都不会影响原羊。

浅拷贝与深拷贝的比较

下表总结了浅拷贝和深拷贝的比较:

特性 浅拷贝 深拷贝
复制方式 只复制对象本身 复制对象及其所有属性和子对象
内存开销 较小 较大
速度 较快 较慢
修改影响 对副本的修改不会影响原件 对副本的修改会影响原件
应用场景 适合复制基本数据类型和简单对象 适合复制复杂对象和嵌套对象

如何在JavaScript中实现浅拷贝和深拷贝

在JavaScript中,可以使用多种方法实现浅拷贝和深拷贝。最简单的方法是使用内置的Object.assign()函数。

浅拷贝

const originalObject = {
  name: 'John',
  age: 30,
  address: {
    street: '123 Main Street',
    city: 'Anytown',
    state: 'CA'
  }
};

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

console.log(copiedObject);
// { name: 'John', age: 30, address: { street: '123 Main Street', city: 'Anytown', state: 'CA' } }

// 对副本的修改不会影响原件
copiedObject.name = 'Jane';

console.log(originalObject);
// { name: 'John', age: 30, address: { street: '123 Main Street', city: 'Anytown', state: 'CA' } }

深拷贝

实现深拷贝的方法有很多,但最常用的方法是使用递归函数。

const deepCopy = (obj) => {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }

  if (Array.isArray(obj)) {
    return obj.map(deepCopy);
  }

  const newObj = {};
  for (const key in obj) {
    newObj[key] = deepCopy(obj[key]);
  }

  return newObj;
};

const originalObject = {
  name: 'John',
  age: 30,
  address: {
    street: '123 Main Street',
    city: 'Anytown',
    state: 'CA'
  }
};

const copiedObject = deepCopy(originalObject);

console.log(copiedObject);
// { name: 'John', age: 30, address: { street: '123 Main Street', city: 'Anytown', state: 'CA' } }

// 对副本的修改会影响原件
copiedObject.name = 'Jane';

console.log(originalObject);
// { name: 'Jane', age: 30, address: { street: '123 Main Street', city: 'Anytown', state: 'CA' } }

总结

在JavaScript中,浅拷贝只复制对象本身,而深拷贝则复制对象及其所有属性和子对象。浅拷贝比较快,内存开销也较小,但它无法复制对象中的嵌套对象。深拷贝比较慢,内存开销也较大,但它可以复制对象中的所有属性和子对象。