什么是深拷贝
我们通常所说的深拷贝,通常所说是拷贝对象,而简单基本数据类型,我们拷贝的直接是数据的值,拷贝的数据和之前的数据完成没有关系。
但对象就不一样了,它在内存给我们存储的是对象的引用地址,如果我们拷贝了,也仅仅是拷贝了对象对象的引用地址。其结果就是,只要有一个变了,另外一个也会跟着变。比如我们在项目中常常需要拷贝一些公用的对象,如果是直接拷贝的话,也仅仅是拷贝了一个对象的引用地址,如果修改了拷贝的值,那么公用的对象也就被修改了,这会造成很大的问题,所以我们引用了深拷贝,所谓深拷贝就是一层层深挖对象里面的基本数据类型,直接拷贝对象里的基本数据类型,从而直接拷贝了一个新的对象。
利用递归深拷贝
const deepCopy=obj=>{
if(typeof obj!=='object'){
return;
}
const newObj=obj instanceof Array?[]:{};
for(let key in obj){
if(obj.hasOwnProperty(key)){
newObj[key]=typeof obj[key]==='object'?deepCopy(obj[key]):obj[key];
}
}
return newObj;
}
const obj1={
a:10,
b:function(){
console.log(1);
},
c:[1,2,3],
d:{
f:[2,{a:20}]
},
e:{
h:true
}
};
const obj2=deepCopy(obj1);
console.log(obj2);
obj2.b=function(){
console.log(2);
};
obj2.b(); //2
obj1.b(); //1
obj2.e=[123];
console.log(obj1.e,obj2.e); //{h: true} [123]
上面代码意思是,我们创建一个拷贝函数,并把结果赋值给变量“deepCopy”,给函数传递一个参数“obj”,当函数运行的时候,首先判断传过来的参数是否是属于对象,如果不属于就返回。
如果是对象,就新建一个对象“ newObj”,同时我们运用一个三目运算符来判断参数“obj”是属于数组类型“[ ]”,还是属于对象类型“{ }”,更具类型的不同来创建不同类型数据“ newObj ”。
然后我们利用for ..in函数类遍历参数“obj”里属性,在变量属性的同时,我们先得判断“key”是否属于参数“obj”里的属性,而不是继承过来的。如果满足就要给新对象"newObj"赋值了。
在赋值的同时,我们还得运用三目运算符判断“obj[key]”是否是对象,如果是就利用函数递归,继续调用“deepCopy()”并传入参数“ obj[key]” 如:“ deepCopy(obj[key])”,否则的话直接赋值。最终返回一个“ newObj”。
在使用时,我们直接调用"deepCopy()",就可以拷贝一个新的对象,而且它们是两个毫无关系的两个新对象,从而实现了深拷贝。