返回

JavaScript 深拷贝与浅拷贝之间的关键差异是什么?

前端

JavaScript 深拷贝与浅拷贝之间的关键差异是什么?

在 JavaScript 中,变量可以存储基本类型的值,如字符串、数字和布尔值,也可以存储引用类型的值,如对象和数组。当我们对变量进行赋值时,如果赋值的是基本类型的值,则会将该值直接复制到新变量中,而不会影响原变量的值。但是,如果赋值的是引用类型的值,则会将该值的引用复制到新变量中,而不会将该值本身复制到新变量中。这种赋值方式被称为浅拷贝。

浅拷贝只复制对象的引用,而不复制对象的值。因此,如果对浅拷贝的对象进行修改,则会影响原对象的值。为了避免这种情况,我们需要使用深拷贝。深拷贝会将对象的引用和值都复制到新变量中,因此对深拷贝的对象进行修改不会影响原对象的值。

深拷贝和浅拷贝的使用场景

浅拷贝通常用于复制基本类型的值或简单的引用类型的值,如字符串、数字和布尔值。深拷贝通常用于复制复杂的对象,如数组和对象。

以下是一些使用浅拷贝和深拷贝的示例:

  • 如果我们要复制一个字符串,则可以使用浅拷贝,因为字符串是基本类型的值。
  • 如果我们要复制一个数组,则可以使用浅拷贝或深拷贝。如果数组中的元素都是基本类型的值,则可以使用浅拷贝。如果数组中的元素是引用类型的值,则需要使用深拷贝。
  • 如果我们要复制一个对象,则可以使用浅拷贝或深拷贝。如果对象中的属性都是基本类型的值,则可以使用浅拷贝。如果对象中的属性是引用类型的值,则需要使用深拷贝。

如何实现深拷贝

JavaScript 中没有内置的深拷贝函数,因此我们需要自己实现深拷贝。实现深拷贝的方法有很多,下面介绍两种最常用的方法:

  • 使用 JSON.parse() 和 JSON.stringify()
const originalObject = {
  name: 'John Doe',
  age: 30,
  address: {
    street: '123 Main Street',
    city: 'Anytown',
    state: 'CA',
    zip: '12345'
  }
};

const deepCopy = JSON.parse(JSON.stringify(originalObject));

deepCopy.address.street = '456 Elm Street';

console.log(originalObject); // { name: 'John Doe', age: 30, address: { street: '123 Main Street', city: 'Anytown', state: 'CA', zip: '12345' } }
console.log(deepCopy); // { name: 'John Doe', age: 30, address: { street: '456 Elm Street', city: 'Anytown', state: 'CA', zip: '12345' } }
  • 使用递归
function deepCopy(object) {
  if (typeof object !== 'object' || object === null) {
    return object;
  }

  if (Array.isArray(object)) {
    return object.map(item => deepCopy(item));
  }

  const newObject = {};
  for (const key in object) {
    newObject[key] = deepCopy(object[key]);
  }

  return newObject;
}

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

const deepCopy = deepCopy(originalObject);

deepCopy.address.street = '456 Elm Street';

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

总结

深拷贝和浅拷贝是 JavaScript 中复制对象的不同方式。深拷贝会将对象的引用和值都复制到新变量中,而浅拷贝只复制对象的引用。深拷贝通常用于复制复杂的对象,如数组和对象,而浅拷贝通常用于复制基本类型的值或简单的引用类型的值,如字符串、数字和布尔值。