返回
深入浅出,剖析 JavaScript 中的深拷贝
前端
2024-02-14 20:51:16
在 JavaScript 中,深拷贝与浅拷贝都是克隆对象的方法。然而,这两种方法在实现方式和效果上存在着本质的区别。
浅拷贝
浅拷贝会创建新对象,但仅仅复制原始对象的一层属性,不会复制嵌套对象。也就是说,新对象中对嵌套对象的引用指向与原始对象中相同的对象。
const obj1 = {
name: 'John',
address: {
street: 'Main Street',
city: 'New York'
}
};
const obj2 = Object.assign({}, obj1);
obj2.name = 'Jane';
obj2.address.street = 'Park Avenue';
console.log(obj1); // { name: 'John', address: { street: 'Park Avenue', city: 'New York' } }
在上面的示例中,obj1
和 obj2
是两个独立的对象,但它们都引用同一个 address
对象。当我们修改 obj2
的 name
和 address.street
属性时,obj1
也受到了影响,因为它们共享同一个 address
对象。
深拷贝
深拷贝会创建新对象,并复制原始对象的所有属性,包括嵌套对象。这意味着,新对象中对嵌套对象的引用指向的是新创建的对象,而不是原始对象中的对象。
const obj1 = {
name: 'John',
address: {
street: 'Main Street',
city: 'New York'
}
};
const obj2 = JSON.parse(JSON.stringify(obj1));
obj2.name = 'Jane';
obj2.address.street = 'Park Avenue';
console.log(obj1); // { name: 'John', address: { street: 'Main Street', city: 'New York' } }
在上面的示例中,obj1
和 obj2
是两个独立的对象,并且它们都具有自己的 address
对象。当我们修改 obj2
的 name
和 address.street
属性时,obj1
不会受到影响,因为它们引用的是不同的 address
对象。
何时使用深拷贝?
深拷贝通常用于以下情况:
- 当您需要在不影响原始对象的情况下修改对象时。
- 当您需要将对象传递给另一个函数或模块时。
- 当您需要将对象存储在数据库或其他持久化存储中时。
何时使用浅拷贝?
浅拷贝通常用于以下情况:
- 当您需要快速复制对象时。
- 当您不需要修改对象的属性时。
- 当您需要将对象作为参数传递给函数或模块时。
实现深拷贝的方法
除了使用 JSON.parse(JSON.stringify())
方法之外,还可以使用以下方法实现深拷贝:
- 使用
lodash
库的_.cloneDeep()
方法。 - 使用
ramda
库的R.clone()
方法。 - 使用
immer
库实现不可变状态管理。
总结
深拷贝和浅拷贝都是 JavaScript 中克隆对象的方法,但在实现方式和效果上存在着本质的区别。深拷贝会创建新对象并复制原始对象的所有属性,包括嵌套对象,而浅拷贝只会创建新对象并复制原始对象的一层属性。深拷贝通常用于需要在不影响原始对象的情况下修改对象的情况,而浅拷贝通常用于需要快速复制对象的情况。