返回

一文掌握深拷贝浅拷贝的区别和应用场景

前端

在编程中,我们经常需要对对象进行复制。在 JavaScript 中,有两种复制对象的方法:深拷贝和浅拷贝。两者之间存在着一些关键的区别,在不同的场景下使用不同的拷贝方法可以带来不同的效果。

1. 什么是浅拷贝?

浅拷贝是指创建一个新的对象,并将其属性值设置为原始对象属性值的副本。如果属性值是基本类型(如字符串、数字、布尔值),则副本将是该值的精确副本。如果属性值是引用类型(如对象、数组),则副本将是该属性值的引用。

举个例子,假设我们有一个对象 person,它具有 name 和 age 两个属性:

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

如果我们对 person 进行浅拷贝,我们会得到一个新的对象 personCopy,它具有与 person 相同的属性值:

const personCopy = {...person};

现在,让我们修改 personCopy 的 name 属性:

personCopy.name = 'Jane Doe';

你会发现,person 的 name 属性也随之改变了!这是因为浅拷贝只复制了属性值的引用,并没有复制属性值本身。因此,当我们修改 personCopy 的 name 属性时,实际上是修改了 person 的 name 属性。

2. 什么是深拷贝?

深拷贝是指创建一个新的对象,并将其属性值设置为原始对象属性值的完全副本。无论属性值是基本类型还是引用类型,副本都将是该值的完全副本。

举个例子,假设我们有一个对象 person,它具有 name 和 age 两个属性:

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

如果我们对 person 进行深拷贝,我们会得到一个新的对象 personCopy,它具有与 person 相同的属性值,但这些属性值是完全独立的副本:

const personCopy = JSON.parse(JSON.stringify(person));

现在,让我们修改 personCopy 的 name 属性:

personCopy.name = 'Jane Doe';

你会发现,person 的 name 属性并没有改变!这是因为深拷贝复制了属性值本身,而不是属性值的引用。因此,当我们修改 personCopy 的 name 属性时,并没有修改 person 的 name 属性。

3. 浅拷贝和深拷贝的区别

下表总结了浅拷贝和深拷贝之间的区别:

特征 浅拷贝 深拷贝
复制属性值 复制引用 复制值本身
修改副本属性值是否影响原始对象
性能 更快 更慢
内存使用 更少 更多
适用场景 当你只想复制对象的部分属性值时 当你想复制整个对象及其所有属性值时

4. 浅拷贝和深拷贝的应用场景

浅拷贝和深拷贝都有各自的应用场景。以下是一些常见的应用场景:

  • 浅拷贝:
    • 当你只想复制对象的部分属性值时。例如,如果你想复制一个对象的 name 和 age 属性,但不想复制它的其他属性,你可以使用浅拷贝。
    • 当你希望修改副本属性值时,并且希望这些修改也反映在原始对象中。例如,如果你想在一个表格中显示一个对象的属性值,并且希望当用户修改表格中的值时,原始对象中的值也会随之改变,你可以使用浅拷贝。
  • 深拷贝:
    • 当你想复制整个对象及其所有属性值时。例如,如果你想复制一个对象并将其存储在数据库中,或者如果你想将一个对象发送给另一个进程,你可以使用深拷贝。
    • 当你想防止修改副本属性值时,并且不希望这些修改反映在原始对象中。例如,如果你想在一个表单中显示一个对象的属性值,并且不希望用户修改表单中的值时,原始对象中的值也会随之改变,你可以使用深拷贝。

5. 总结

浅拷贝和深拷贝是 JavaScript 中复制对象的两 种不同方法。浅拷贝只复制属性值的引用,而深拷贝复制属性值本身。浅拷贝更快,但它可能会导致修改副本属性值时原始对象也受到影响。深拷贝更慢,但它可以防止修改副本属性值时原始对象也受到影响。根据不同的场景,选择合适的拷贝方法可以带来不同的效果。