返回

揭秘JavaScript 深拷贝和浅拷贝

前端




在JavaScript中,数据类型分为基本类型(也称原始类型)和引用类型。基本类型包括字符串、数字、布尔值、undefined和null,它们在内存中是独立存在的,变量直接存储它们的值。引用类型包括对象和数组,变量存储的不是它们的值,而是指向它们的引用,指向内存中存储它们的位置。

浅拷贝 就是只复制对象的一层属性,如果对象中有引用类型,浅拷贝不会复制该引用类型的内容,而是复制引用类型在内存中的地址。这意味着,如果对浅拷贝的对象进行修改,也会影响到原始对象。

深拷贝 就是递归地复制对象的所有属性,包括引用类型的内容。这意味着,对深拷贝的对象进行修改,不会影响到原始对象。

以下代码演示了浅拷贝和深拷贝的区别:

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

// 浅拷贝
const personCopy = Object.assign({}, person);

// 修改浅拷贝的对象
personCopy.name = 'Jane';
personCopy.address.street = '456 Elm Street';

// 查看原始对象
console.log(person);
// { name: 'John', age: 30, address: { street: '456 Elm Street', city: 'New York', state: 'NY' } }

// 深拷贝
const personCopyDeep = JSON.parse(JSON.stringify(person));

// 修改深拷贝的对象
personCopyDeep.name = 'Jane';
personCopyDeep.address.street = '456 Elm Street';

// 查看原始对象
console.log(person);
// { name: 'John', age: 30, address: { street: '123 Main Street', city: 'New York', state: 'NY' } }

在这个例子中,浅拷贝只复制了person对象的一层属性,当修改personCopy对象的address属性时,person对象的address属性也会被修改。深拷贝则复制了person对象的所有属性,包括address对象的属性,当修改personCopyDeep对象的address属性时,person对象的address属性不会被修改。

何时使用浅拷贝和深拷贝

浅拷贝和深拷贝都有各自的应用场景。浅拷贝通常用于复制简单对象,例如字符串、数字和布尔值。深拷贝通常用于复制复杂对象,例如对象和数组。

以下是一些浅拷贝的应用场景:

  • 克隆一个基本类型值
  • 克隆一个引用类型值,但不需要修改它
  • 将一个对象作为参数传递给函数,而不想修改原始对象

以下是一些深拷贝的应用场景:

  • 克隆一个引用类型值,并需要修改它
  • 将一个对象存储到数据库中,而不想修改原始对象
  • 将一个对象发送到另一个进程,而不想修改原始对象

总结

浅拷贝和深拷贝是JavaScript中复制对象的重要工具。浅拷贝只复制对象的一层属性,深拷贝则复制对象的所有属性。浅拷贝通常用于复制简单对象,深拷贝通常用于复制复杂对象。