总结
- 浅拷贝适用于只需要复制一层数据的场景。
- 深拷贝适用于多层嵌套的对象,需要确保原数据完全不被影响时。
浅拷贝
浅拷贝只复制对象的第一层属性,对于嵌套的引用类型(如对象或数组),它复制的是引用地址,而不是实际的值。
常见的浅拷贝方法:
1、Object.assign()
const obj = { a: 1, b: { c: 2 } };
const shallowCopy = Object.assign({}, obj);
shallowCopy.b.c = 3;
console.log(obj.b.c); // 输出 3,原对象被修改
2、展开运算符 (...
)
const obj = { a: 1, b: { c: 2 } };
const shallowCopy = { …obj };
shallowCopy.b.c = 3;
console.log(obj.b.c); // 输出 3,原对象被修改
处理嵌套的引用类型:
浅拷贝在处理嵌套的引用类型时,仅复制引用地址,而不是实际内容。这意味着拷贝后的对象或数组内部的嵌套对象(或数组)和原对象共享同一个引用地址。
如果你修改了拷贝对象中的嵌套数据,原对象的对应部分也会随之改变。
const original = { x: 10, y: { z: 20 } };
const shallowCopy = { …original }; // 浅拷贝
console.log(shallowCopy); // { x: 10, y: { z: 20 } }
// 修改 shallowCopy 中的嵌套对象
shallowCopy.y.z = 30;
console.log(original.y.z); // 输出 30
过程解释
- 浅拷贝时,
shallowCopy.y
指向了original.y
的引用地址,而不是值本身。 - 修改
shallowCopy.y.z
的值时,实际修改的是original.y
所指向的内存地址中的值。 - 因此,
original.y.z
和shallowCopy.y.z
都变成了30
。
深拷贝
深拷贝会递归复制对象的所有层级,确保嵌套的引用类型也会被完整复制,两个对象互不影响。
常见的深拷贝方法:
1、JSON 方法 使用 JSON.stringify()
和 JSON.parse()
可以快速实现深拷贝,但有以下限制:
- 无法复制函数
- 无法处理
undefined
、Symbol
等特殊值
const obj = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(obj));
deepCopy.b.c = 3;
console.log(obj.b.c); // 输出 2,原对象未被修改
2、递归方法 手动编写递归逻辑,完整复制每一层。
function deepClone(obj) {
if (obj === null || typeof obj !== “object”) return obj;
const copy = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
copy[key] = deepClone(obj[key]);
}
}
return copy;
}
const obj = { a: 1, b: { c: 2 } };
const deepCopy = deepClone(obj);
deepCopy.b.c = 3;
console.log(obj.b.c); // 输出 2
3、
使用库
- Lodash 提供了一个强大的深拷贝方法
_.cloneDeep
。
const _ = require(“lodash”);
const obj = { a: 1, b: { c: 2 } };
const deepCopy = _.cloneDeep(obj);
deepCopy.b.c = 3;
console.log(obj.b.c); // 输出 2