深拷贝的方法:
- JSON.parse(JSON.stringify(obj))
- 手写递归深拷贝
- lodash的_.cloneDeep()方法
- npm的clone-deep包
使用 JSON.parse(JSON.stringify(obj)) 进行深拷贝,处理Date对象、undefined、null、function 等数据会出错,所以非常不建议使用。以下为JS手写递归深拷贝的基本思路:
// 测试数据
let obj = {
numberParams: 1,
functionParams: () => {
console.log("昨天基金全是绿的,只有我的眼睛是红的");
},
objParams: {
a: 1,
b: 2,
},
};
// 深拷贝函数
// Map解决循环引用问题,WeakMap解决垃圾回收问题
let deepClone = (target = {
}, map = new WeakMap()) => {
// 递归条件
if (typeof target === "object" && typeof target !== null) {
// 如果在表中已经存在该对象,则直接返回表中引用的对象,而不是重复递归,导致死循环栈溢出
if (map.get(target)) {
return map.get(target);
}
// 如果目标是引用类型,遍历复制目标的所有属性
let cloneTarget = Array.isArray(target) ? [] : {
}; // 区分是数组还是对象
map.set(target, cloneTarget); // 引用类型,在表中记录下来
for (const key in target) {
cloneTarget[key] = deepClone(target[key], map); // 递归核心
}
return cloneTarget;
} else return target; // 如果目标不是引用类型,则直接赋值
};
// 测试
let obj2 = deepClone(obj);
obj2.objParams.a = 123123123123;
console.log(obj);
console.log(obj2);