返回

揭秘 ES6 复制真相:解构赋值、Object.assign 和 [].concat 间的深拷贝迷雾

前端

ES6 复制数据:浅拷贝还是深拷贝?

在 JavaScript 中,当我们复制对象或数组时,经常会遇到浅拷贝和深拷贝的概念。浅拷贝只复制对象的引用,而深拷贝则复制对象的实际数据。了解这两种复制方式的区别对于有效管理数据至关重要。

浅拷贝

浅拷贝只复制对象的引用,这意味着对新对象所做的任何更改都会影响原始对象。

深拷贝

深拷贝复制对象的实际数据,因此对新对象所做的任何更改都不会影响原始对象。

ES6 复制方法:解构赋值、Object.assign、[].concat

ES6 提供了三种主要方法来复制数据:解构赋值、Object.assign 和 [].concat。

1. 解构赋值

const newObject = { ...oldObject };

解构赋值创建一个新对象,并为每个属性分配旧对象的同名属性值。它是浅拷贝,这意味着对 newObject 所做的任何更改都会影响 oldObject

2. Object.assign

const newObject = Object.assign({}, oldObject);

Object.assign 函数创建一个新对象,并为新对象分配旧对象的可枚举属性。它是浅拷贝,这意味着对 newObject 所做的任何更改都会影响 oldObject

3. [].concat

const newArray = [...oldArray];

[].concat 方法创建一个新数组,并为新数组添加旧数组中的所有元素。它是浅拷贝,这意味着对 newArray 所做的任何更改都会影响 oldArray

实战示例

为了清晰地展示这三种方法之间的区别,我们使用以下示例对象:

const oldObject = {
  name: "John Doe",
  age: 30,
  address: {
    street: "Main St",
    number: 123,
  },
};

浅拷贝示例

// 使用解构赋值进行浅拷贝
const newObject1 = { ...oldObject };

// 使用 Object.assign 进行浅拷贝
const newObject2 = Object.assign({}, oldObject);

// 使用 [].concat 进行浅拷贝
const newArray = [...oldArray];

// 修改浅拷贝
newObject1.name = "Jane Doe";
newObject2.age = 35;
newArray[0] = "New Street";

在上述示例中,对浅拷贝对象和数组所做的更改也影响了原始对象和数组。

深拷贝示例

为了进行深拷贝,我们需要使用递归或库函数。例如:

// 使用 JSON.parse(JSON.stringify()) 进行深拷贝
const newObject3 = JSON.parse(JSON.stringify(oldObject));

// 使用 Lodash 库函数进行深拷贝
const newObject4 = _.cloneDeep(oldObject);

在新对象上所做的更改不会影响原始对象。

结论

在 ES6 中,解构赋值、Object.assign 和 [].concat 这三个方法都是浅拷贝,这意味着对新对象或数组所做的任何更改都会影响原始对象或数组。为了进行深拷贝,我们需要使用递归或库函数。

在选择复制方法时,重要的是要了解浅拷贝和深拷贝之间的区别,并选择最适合特定需求的方法。浅拷贝对于对原始对象或数组进行后续操作很有用,而深拷贝则对于防止意外修改原始数据很有用。