js中递归实现深克隆

深克隆与浅克隆

  • 浅克隆:克隆前后会互相影响,如果改变克隆前的内容会影响克隆后的内容,反之亦然。
  • 深克隆:克隆前后不会互相影响

注意:

  • 利用...展开运算符进行的克隆和Object.assign进行的克隆都是浅克隆,它只能克隆一层
var obj = {a:1,b:{c:2}};
var o = {...obj};
console.log(o===obj)//false
console.log(o);//{a: 1, b: {c:2}}
obj.b.c = 200;
console.log(o);//{a: 1, b: {c:200}}
//------------------
var ary = [1,2,3];
var ary1 = [ary];
var ary2 = [...ary1];
console.log(ary2 === ary1);//false
console.log(ary2);//[1,2,3]
ary1[0][0]=100;
console.log(ary2);//[100,2,3]
  • 利用JSON.parse(JSON.stringify())实现的是深克隆,但是当对象属性值是undefined或是函数时不能进行克隆
var obj9 = {a:1,b:undefined,c:null,d:function(){}};
var obj8 = JSON.parse(JSON.stringify(obj9));
console.log(obj8);//{a: 1, c: null}
  • 递归实现深克隆
function deepClone(obj,hash = new WeakMap()){
    if(obj == undefined){// 如果当前obj是null或undefined就不进行深克隆
        return obj;
    }
    if(obj instanceof Date){// 如果当前obj是日期就会产生一个新的日期
        return new Date(obj);
    }
    if(obj instanceof RegExp){// 如果当前obj是正则就会产生一个新正则
        return new RegExp(obj);
    }
    if(typeof obj!=="object"){// 如果obj是普通值就直接接返回,是对象的话进行深克隆
        return obj;
    }
    if(hash.get(obj)){
        return hash.get(obj);
    }
    let cloneObj = new obj.__proto__.constructor;
    hash.set(obj,cloneObj);//解决对象中的循环引用
    for(let key in obj){
        cloneObj[key] = deepClone(obj[key],hash);
    }
    return cloneObj;
}
var obj = {a:1,b:undefined,c:null,d:function(){}};
// obj.o = obj;//这是循环引用
var obj1 = deepClone(obj);
console.log(obj1);//{a: 1, b: undefined, c: null, d: ƒ}

你可能感兴趣的:(js)