1. 理解深拷贝的核心需求
在编程实践中,我们经常会遇到需要保留对象原始状态的情况。想象你正在开发一个表单编辑系统——用户开始编辑时,你需要保存表单的初始值;当用户点击"保存"按钮时,你需要比较当前值与原始值,判断哪些字段被修改过。这就是深拷贝(Deep Copy)的典型应用场景。
浅拷贝(Shallow Copy)只复制对象的引用,新旧对象共享同一块内存。而深拷贝会递归复制对象及其所有子对象,创建一个完全独立的副本。对于包含嵌套结构或引用类型的对象,深拷贝能确保原始对象和拷贝对象互不影响。
关键区别:浅拷贝后修改新对象会影响原对象,深拷贝则完全隔离两个对象。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 实现深拷贝的常见方法
2.1 JSON序列化反序列化
最快捷的深拷贝方式是利用JSON:
javascript复制function deepCopy(obj) {
return JSON.parse(JSON.stringify(obj));
}
这种方法适用于大多数场景,但有明显限制:
- 会丢失函数、undefined等JSON不支持的类型
- 无法处理循环引用(对象A引用B,B又引用A)
- 特殊对象如Date会变成字符串
2.2 递归手动拷贝
更可靠的方式是手动实现递归拷贝:
javascript复制function deepCopy(obj, hash = new WeakMap()) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
// 处理循环引用
if (hash.has(obj)) return hash.get(obj);
let copy = Array.isArray(obj) ? [] : {};
hash.set(obj, copy);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
copy[key] = deepCopy(obj[key], hash);
}
}
return copy;
}
这个实现解决了循环引用问题,保留了原型链,是更完整的解决方案。
2.3 使用第三方库
对于复杂项目,推荐使用成熟工具库:
- Lodash的
_.cloneDeep() - jQuery的
$.extend(true, {}, obj) - Immutable.js(提供不可变数据结构)
这些库经过充分测试,能处理各种边界情况。
3. 深拷贝的性能优化策略
深拷贝是昂贵的操作,特别是对于大型对象。以下优化策略值得考虑:
3.1 按需拷贝
不是所有场景都需要完
