const wm = new WeakMap();//用于解决循环引用,避免陷入死循环
function deepClone(target) {
let result;
if (typeof target === 'object') {
// null
if (target === null) {
result = target;
}
// Array
else if (Array.isArray(target)) {
result = [];
target.forEach(item => result.push(deepClone(item)));
}
// Date
else if (target instanceof Date) {
result = new Date(target);
}
// regular expression
else if (target instanceof RegExp) {
result = new RegExp(target);
} else {
// detect circular reference
// 用WeakMap的key保存原对象的引用记录, value是对应的深拷贝对象的引用
// 例如: a:{b:{c:{d: null}}}, d=a, a 的深拷贝对象是 copy, 则 weakmap 里保存一条 a->copy 记录
// 当递归拷贝到d, 发现d指向a,而a已经存在于weakmap,则让新d指向copy
if (wm.has(target)) {
result = wm.get(target);
} else {
result = {};
wm.set(target, result);
for (let prop in target) {
result[prop] = deepClone(target[prop]);
}
}
}
} else {
result = target;
}
return result;
}
(function () {
const a = {
num: 123,
say() {
return 'Hello';
},
arr: [1, 2, [4, {name: 'Jack'}]],
n: null,
un: undefined,
d: new Date(),
reg: /[a-z0-9]+/,
b: {
c: {
d: null
}
}
};
a.b.c.d = a;
const copy = deepClone(a);
console.log(copy)
console.log(copy === a) // false
console.log(copy.say()); // Hello
console.log(copy.arr);
console.log(copy.arr[2][1] === a.arr[2][1]); // false
console.log(copy.b.c.d === copy) // true,循环引用得到复制
})();
``
JavaScript实现深拷贝
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 简介 注:浅拷贝和深拷贝都只针对于像Object, Array这样的复杂对象。浅拷贝:浅拷贝只是复制了内存地址,如...
- 下面代码中引用的部分方法在这篇文章中最后一部分:https://www.jianshu.com/p/6765dc5...