手写实现深拷贝(不考虑循环引用)
function deepClone(obj, newObj) {
newObj = newObj || {};
for (let i in obj) {
if (typeof obj[i] === "object") {
newObj[i] =
Object.prototype.toString.call(obj[i]) === "[object Array]" ? [] : {};
deepClone(obj[i], newObj[i]);
} else {
newObj[i] = obj[i];
}
}
}
考虑循环引用实现深拷贝
在实现兼容循环引用之前,需要铺垫一下WeakMap的知识,实现的主要原理就是基于WeakMap的。
WeakMap可以算是Map的一个加强版。
同样都是key , value的形式保存变量,WeakMap和Map最大的区别就是,WeakMap是弱引用的,当它的键在外部失去引用时,这组键值对自动删除。
基于WeakMap的原理,我们就可以全面完善深拷贝的代码。
function deepClones(origin, map = new WeakMap()) {
// origin == undefined可以同时判断undefined和null
if (origin == undefined || typeof origin !== "object") {
return origin;
} else if (origin instanceof Date) {
return new Date(origin);
} else if (origin instanceof RegExp) {
return new RegExp(origin);
} else {
const key = map.get(origin);
if (key) {
return key;
}
const target = new origin.constructor();
map.set(origin, target);
for (let k in origin) {
target[k] = deepClones(origin[k], map);
}
return target;
}
}