深拷贝
两种深拷贝的实现
js
const obj = {
name: 'xiaoyin',
age: 24,
career: '前端小菜鸡',
info: {
filed: ['JS', 'CSS', 'HTML'],
framework: ['Vue', 'React', 'Angular'],
student: [
{
name: 'xiaoyin',
age: 24,
},
{
name: 'xiaozhu',
age: 20,
},
],
},
hobby: ['跑步', '爬山'],
};
具体实现
js
function deepClone(origin, target) {
var tar = target || {};
var toStr = Object.prototype.toString;
var arrayType = '[object Array]';
if (typeof origin !== 'object' || origin === null) return origin;
for (var key in origin) {
if (origin.hasOwnProperty(key)) {
if (typeof origin[key] === 'object' && origin[key] !== null) {
tar[key] = toStr.call(origin[key]) === arrayType ? [] : {};
deepClone(origin[key], tar[key]);
} else {
tar[key] = origin[key];
}
}
}
return tar;
}
const newObj = deepClone(obj);
console.log(newObj);
js
function deepClone(origin, hashMap = new WeakMap()) {
// 此处写origin == undefined是因为==下undefined和null是相等的
if (typeof origin !== 'object' || origin == undefined) return origin;
if (origin instanceof Date) {
return new Date(origin);
}
if (origin instanceof RegExp) {
return new RegExp(origin);
}
const hasKey = hashMap.get(origin);
if (hasKey) {
return hasKey;
}
const target = new origin.constructor();
hashMap.set(origin, target);
for (let key in origin) {
if (origin.hasOwnProperty(key)) {
target[key] = deepClone(origin[key], hashMap);
}
}
return target;
}
// const newObj = deepClone(obj);
// newObj.info.filed[0] = '卧槽';
// console.log(newObj,'newObj')
// console.log(obj)
//对象相互嵌套时候循环引用 若是直接传入此对象,会导致递归函数栈溢出 没有终止循环的条件
//所以采用WeakMap来解决这个问题 WeakMap是弱引用的Map并且其key可以是基本数据类型以外的其余类型
//因此此处可以使用WeakMap来存储已经访问过的对象,当再次访问到已经访问过的对象时,直接返回该对象即可,顺带终止了递归
// WeakMap只能以复杂数据类型作为key,并且key值是弱引用,对于垃圾回收更加友好。
let test1 = {};
let test2 = {};
test1.a = test2;
test2.b = test1;
console.log(deepClone(test1));