对象复制
JavaScript 中复制对象的多种方法。
浅拷贝
扩展运算符
const original = { a: 1, b: { c: 2 } };
// 浅拷贝
const copy = { ...original };
// 修改顶层属性不影响原对象
copy.a = 10;
console.log(original.a); // 1
// 但嵌套对象是引用
copy.b.c = 20;
console.log(original.b.c); // 20 - 原对象被修改
Object.assign()
const original = { a: 1, b: 2, c: 3 };
// 复制到新对象
const copy = Object.assign({}, original);
// 或复制到现有对象
const target = { d: 4 };
Object.assign(target, original);
console.log(target); // { d: 4, a: 1, b: 2, c: 3 }
Object.create()
const original = { a: 1, b: 2 };
// 创建原型为 original 的新对象
const copy = Object.create(original);
// copy 继承 original 的属性
console.log(copy.a); // 1
深拷贝
JSON 方法(简单场景)
const original = { a: 1, b: { c: 2 }, d: 'test' };
// 深拷贝(注意限制)
const copy = JSON.parse(JSON.stringify(original));
// 限制:
// - 不能处理函数
// - 不能处理 undefined
// - 不能处理 Date(会变成字符串)
// - 不能处理循环引用
// - 不能处理 RegExp
const withFunc = { a: 1, fn: () => {} };
JSON.parse(JSON.stringify(withFunc)); // { a: 1 } - 函数丢失
structuredClone()(现代浏览器)
const original = {
a: 1,
b: { c: 2 },
d: new Date(),
e: new RegExp('/test/')
};
// 原生深拷贝 API
const copy = structuredClone(original);
console.log(copy.d instanceof Date); // true
console.log(copy.e instanceof RegExp); // true
递归实现
function deepClone(obj, hash = new WeakMap()) {
// 处理非对象
if (obj === null || typeof obj !== 'object') {
return obj;
}
// 处理 Date
if (obj instanceof Date) {
return new Date(obj);
}
// 处理 RegExp
if (obj instanceof RegExp) {
return new RegExp(obj);
}
// 处理循环引用
if (hash.has(obj)) {
return hash.get(obj);
}
// 创建新对象
const clone = Array.isArray(obj) ? [] : {};
hash.set(obj, clone);
// 递归拷贝属性
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepClone(obj[key], hash);
}
}
return clone;
}
const original = { a: 1, b: { c: 2 } };
const copy = deepClone(original);
copy.b.c = 20;
console.log(original.b.c); // 2 - 原对象不受影响
使用 lodash
import _ from 'lodash';
const original = { a: 1, b: { c: 2 } };
// 深拷贝
const copy = _.cloneDeep(original);
选择建议
| 场景 | 推荐方法 |
|---|---|
| 简单对象 | { ...obj } |
| 需要深拷贝 | structuredClone() |
| 兼容旧浏览器 | JSON 方法或 lodash |
| 处理复杂类型 | lodash cloneDeep |