返回

JS深浅拷贝详解

前端

引言

在 JavaScript 中,变量可以存储不同类型的数据,其中一种常见的数据类型是对象。对象是一种复杂的数据类型,可以包含多个属性,每个属性都有一个键和一个值。当我们给一个对象赋值时,可以是浅拷贝或深拷贝。

浅拷贝与深拷贝的区别

浅拷贝只复制对象的属性,而深拷贝会复制对象的属性和属性值。换句话说,浅拷贝只复制了对象的引用,而深拷贝复制了对象的副本。

浅拷贝的实现

const obj1 = {
  name: 'John Doe',
  age: 30
};

const obj2 = obj1;

// 修改 obj2 的属性值
obj2.age = 31;

// obj1 的属性值也发生了变化
console.log(obj1.age); // 31

在这个例子中,我们使用 const obj2 = obj1;obj1 赋值给 obj2。这实际上是创建了 obj1 的一个引用,而不是副本。因此,当我们修改 obj2 的属性值时,obj1 的属性值也会发生变化。

深拷贝的实现

const obj1 = {
  name: 'John Doe',
  age: 30
};

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

// 修改 obj2 的属性值
obj2.age = 31;

// obj1 的属性值没有变化
console.log(obj1.age); // 30

在这个例子中,我们使用 JSON.stringify()obj1 转换成 JSON 字符串,然后再使用 JSON.parse() 将 JSON 字符串转换成对象。这种方法可以创建 obj1 的副本,因此当我们修改 obj2 的属性值时,obj1 的属性值不会发生变化。

性能考虑

深拷贝比浅拷贝的性能开销更大,因为深拷贝需要复制对象的所有属性和属性值。因此,在选择使用哪种拷贝方式时,需要考虑性能和安全性的权衡。

ES6 中的深拷贝

ES6 中提供了 Object.assign() 方法,可以实现深拷贝。Object.assign() 方法的语法如下:

Object.assign(target, ...sources)

其中,target 是要复制到的对象,sources 是要复制的对象。

const obj1 = {
  name: 'John Doe',
  age: 30
};

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

// 修改 obj2 的属性值
obj2.age = 31;

// obj1 的属性值没有变化
console.log(obj1.age); // 30

总结

浅拷贝只复制对象的属性,而深拷贝会复制对象的属性和属性值。深拷贝比浅拷贝的性能开销更大,但更安全。ES6 中提供了 Object.assign() 方法,可以实现深拷贝。