返回

深拷贝与浅拷贝的区别与应用指南

前端

浅拷贝与深拷贝概述

在 JavaScript 中,对象是一种复杂的数据结构,它可以包含各种各样的数据,包括基本类型数据(如字符串、数字、布尔值等)和引用类型数据(如数组、对象等)。当我们需要复制一个对象时,有两种不同的方法:浅拷贝和深拷贝。

浅拷贝 :浅拷贝只复制对象本身的属性,不会复制对象引用的其他对象。这意味着,如果对象本身包含引用类型的数据,那么浅拷贝只会复制这些数据的引用,而不是复制这些数据本身。

深拷贝 :深拷贝不仅复制对象本身的属性,还会复制对象引用的其他对象。这意味着,如果对象本身包含引用类型的数据,那么深拷贝不仅会复制这些数据的引用,还会复制这些数据本身。

浅拷贝与深拷贝的实现

在 JavaScript 中,可以使用多种方法来实现浅拷贝和深拷贝。下面分别介绍两种最常见的方法:

浅拷贝

Object.assign() 方法

Object.assign() 方法是 JavaScript 中内置的浅拷贝方法,它可以将一个或多个源对象的可枚举属性复制到目标对象。Object.assign() 方法的语法如下:

Object.assign(target, ...sources)

其中:

  • target:目标对象,用于接收源对象的可枚举属性。
  • sources:源对象,可以是多个对象,用于提供可枚举属性。

下面是一个浅拷贝的示例代码:

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

const obj2 = Object.assign({}, obj1);

console.log(obj2);

输出结果:

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

从输出结果可以看出,obj2 与 obj1 具有相同的值,但是它们是不同的对象。这意味着,修改 obj2 的属性不会影响 obj1,反之亦然。

深拷贝

JSON.parse(JSON.stringify()) 方法

JSON.parse(JSON.stringify()) 方法是一种实现深拷贝的常见方法。它先将对象转换为 JSON 字符串,然后将 JSON 字符串解析为新的对象。JSON.parse(JSON.stringify()) 方法的语法如下:

JSON.parse(JSON.stringify(obj))

其中:

  • obj:要复制的对象。

下面是一个深拷贝的示例代码:

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

const obj2 = JSON.parse(JSON.stringify(obj1));

console.log(obj2);

输出结果:

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

从输出结果可以看出,obj2 与 obj1 具有相同的值,但是它们是不同的对象。这意味着,修改 obj2 的属性不会影响 obj1,反之亦然。

浅拷贝与深拷贝的应用场景

浅拷贝和深拷贝在不同的场景下都有各自的应用。

浅拷贝的应用场景

浅拷贝通常用于复制基本类型数据和引用类型数据的引用。例如:

  • 复制基本类型数据:如果我们只关心基本类型数据的副本,而不关心它所引用的其他对象,那么可以使用浅拷贝。例如,如果我们只想复制一个字符串或数字,那么可以使用浅拷贝。
  • 复制引用类型数据的引用:如果我们只关心引用类型数据的副本,而不关心它所引用的其他对象,那么可以使用浅拷贝。例如,如果我们只想复制一个数组或对象,那么可以使用浅拷贝。

深拷贝的应用场景

深拷贝通常用于复制引用类型数据及其所引用的其他对象。例如:

  • 复制引用类型数据及其所引用的其他对象:如果我们不仅关心引用类型数据的副本,还关心它所引用的其他对象,那么可以使用深拷贝。例如,如果我们想复制一个数组或对象,以及它们所包含的所有元素或属性,那么可以使用深拷贝。
  • 防止对象修改的副作用:如果我们不希望修改对象副本影响到原始对象,那么可以使用深拷贝。例如,如果我们有一个对象,并且我们想在不影响原始对象的情况下修改它的副本,那么可以使用深拷贝。

结论

浅拷贝和深拷贝是 JavaScript 中两种不同的对象复制方法。浅拷贝只复制对象本身的属性,不会复制对象引用的其他对象。深拷贝不仅复制对象本身的属性,还会复制对象引用的其他对象。浅拷贝和深拷贝在不同的场景下都有各自的应用。