返回

揭开老生常谈的深浅拷贝面纱

前端




前言

在聊深浅拷贝之前,先复习一下JS中的数据类型:基本类型和引用类型。

基本类型:

  • undefined
  • null
  • Boolean
  • String
  • Number
  • Symbol
  • ...

引用类型:

  • Object
  • Array
  • Function
  • Date
  • RegExp
  • ...

基本类型变量存储在栈内存中,而引用类型变量存储在堆内存中。栈内存存储的是基本类型变量的值,堆内存存储的是引用类型变量的地址。

当我们对基本类型变量进行赋值时,会将值直接复制到新的变量中。当我们对引用类型变量进行赋值时,会将引用类型变量的地址复制到新的变量中。

深拷贝和浅拷贝

深拷贝和浅拷贝都是一种复制对象的方式。

深拷贝:

深拷贝会复制对象的所有属性,包括基本类型属性和引用类型属性。

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

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

console.log(obj2.address === obj1.address); // false

在上面的示例中,obj1obj2 是两个独立的对象。obj1.addressobj2.address 是两个独立的对象。

浅拷贝:

浅拷贝只复制对象的引用类型属性,不会复制对象的引用类型属性。

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

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

console.log(obj2.address === obj1.address); // true

在上面的示例中,obj1obj2 是两个独立的对象。但是,obj1.addressobj2.address 是同一个对象。

深拷贝和浅拷贝的比较

特征 深拷贝 浅拷贝
复制类型 复制对象的所有属性,包括基本类型属性和引用类型属性 只复制对象的引用类型属性,不会复制对象的引用类型属性
内存分配 新的对象在堆内存中分配 新的对象在栈内存中分配
性能 性能较差 性能较好
用途 当我们需要创建一个与原始对象完全独立的新对象时使用 当我们需要创建一个与原始对象共享某些属性的新对象时使用

结论

深拷贝和浅拷贝都是复制对象的方式。深拷贝会复制对象的所有属性,浅拷贝只复制对象的引用类型属性。深拷贝的性能较差,浅拷贝的性能较好。当我们需要创建一个与原始对象完全独立的新对象时使用深拷贝,当我们需要创建一个与原始对象共享某些属性的新对象时使用浅拷贝。