2025年09月08日/ 浏览 4
在实际开发中,我们经常需要复制一个对象以避免直接修改原始数据。本文将全面讲解JavaScript中对象克隆的各种方法,帮助您选择最适合业务场景的解决方案。
当直接使用赋值操作符=
时,我们只是创建了对原始对象的引用而非真正的副本。修改新变量会影响原始对象:
javascript
const original = { name: 'Alice' };
const copy = original;
copy.name = 'Bob';
console.log(original.name); // 输出'Bob'(非预期结果)
javascript
const shallowCopy = { ...original };
javascript
const shallowCopy = Object.assign({}, original);
注意事项:
– 只复制对象的第一层属性
– 嵌套对象仍然是引用关系
– 无法复制原型链上的属性和不可枚举属性
javascript
const deepCopy = JSON.parse(JSON.stringify(original));
局限性:
– 无法处理函数、Symbol等特殊类型
– 会丢失undefined属性
– 循环引用会导致报错
javascript
function deepClone(obj, hash = new WeakMap()) {
if (obj === null) return null;
if (typeof obj !== ‘object’) return obj;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
if (hash.has(obj)) return hash.get(obj);
const cloneObj = new obj.constructor();
hash.set(obj, cloneObj);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
cloneObj[key] = deepClone(obj[key], hash);
}
}
return cloneObj;
}
通过WeakMap存储已克隆对象,遇到相同引用时直接返回存储的副本:
javascript
const obj = { self: null };
obj.self = obj;
const cloned = deepClone(obj); // 正确处理循环引用
| 场景 | 推荐方法 |
|———————|———————–|
| 简单对象浅拷贝 | 扩展运算符 |
| 需要保留原型链 | Object.create |
| 复杂对象深拷贝 | 递归实现或JSON方案 |
| 需要处理特殊类型 | 自定义克隆函数 |
工程建议:在项目中统一封装克隆工具函数,避免不同实现方式带来的维护问题。