返回

JavaScript手撕系列之浅拷贝和深拷贝

前端

前言

在 JavaScript 中,变量可以存储基本数据类型和对象数据类型。基本数据类型包括字符串、数字、布尔值、null、undefined 和 Symbol。对象数据类型则包括对象、数组、函数等。

当我们对基本数据类型变量进行赋值时,实际操作的是变量本身。因此,对基本数据类型变量的拷贝实际上是创建了一个新变量,并赋予其与原变量相同的值。

对象数据类型变量则不同,它们存储的是对象的引用,而不是对象本身。因此,对对象数据类型变量进行赋值时,实际操作的是变量指向的对象的引用。

浅拷贝与深拷贝

JavaScript 中的拷贝主要分为浅拷贝和深拷贝。

浅拷贝

浅拷贝是指只拷贝对象的第一层属性,不会拷贝嵌套的对象。

const obj1 = {
  name: 'John',
  age: 30,
  address: {
    street: 'Main Street',
    city: 'New York',
    state: 'NY',
  },
};

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

obj2.name = 'Jane';
console.log(obj1); // { name: 'Jane', age: 30, address: { street: 'Main Street', city: 'New York', state: 'NY' } }

在上面的示例中,我们使用 Object.assign() 方法对 obj1 进行浅拷贝,创建了一个新的对象 obj2。当我们修改 obj2name 属性时,obj1name 属性也会被修改,因为它们指向同一个对象。

深拷贝

深拷贝是指拷贝对象的所有属性,包括嵌套的对象。

const obj1 = {
  name: 'John',
  age: 30,
  address: {
    street: 'Main Street',
    city: 'New York',
    state: 'NY',
  },
};

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

obj2.name = 'Jane';
console.log(obj1); // { name: 'John', age: 30, address: { street: 'Main Street', city: 'New York', state: 'NY' } }

在上面的示例中,我们使用 JSON.stringify()JSON.parse() 方法对 obj1 进行深拷贝,创建了一个新的对象 obj2。当我们修改 obj2name 属性时,obj1name 属性不会被修改,因为它们指向不同的对象。

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

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

浅拷贝的应用场景

  • 当我们需要拷贝一个对象,并且不需要修改嵌套的对象时,可以使用浅拷贝。
  • 当我们需要拷贝一个对象,并且嵌套的对象很少时,可以使用浅拷贝。

深拷贝的应用场景

  • 当我们需要拷贝一个对象,并且需要修改嵌套的对象时,可以使用深拷贝。
  • 当我们需要拷贝一个对象,并且嵌套的对象很多时,可以使用深拷贝。

总结

浅拷贝和深拷贝是 JavaScript 中常用的两种拷贝方式。浅拷贝只拷贝对象的第一层属性,不会拷贝嵌套的对象。深拷贝则拷贝对象的所有属性,包括嵌套的对象。浅拷贝和深拷贝在不同的场景下都有各自的应用。