我特别想写这篇,因为我看到了一篇非常非常优秀的博客,讲的巨好!直接贴上链接,强烈建议大家去阅读原博主的 https://www.cnblogs.com/echolun/p/7889848.html
1.深拷贝和浅拷贝的区别
B复制A,A变,B变,浅拷贝。
B复制A,A变,B不变,深拷贝。
举个简单example
平常的a赋值给b,a变,b并不会变。而对于对象obj2,这种简单的赋值,obj变,obj2变,就是浅拷贝了。
这是为啥呢?这就要我们从数据类型说起了。。。。
2.基本数据类型和引用数据类型
基本数据类型有:string,boolean,null,number,undefined,symbol(ES6),BigInt(ES10)
而引用数据类型:object,list,function。
他们之间的赋值方式是不一样的。
看完图,其实就一目了然了,对于基本数据类型的赋值,栈内存会开辟一个新的内存,而对于引用数据类型,其实赋的不是值,而是地址,这个地址指向原堆内存的值。所以只要堆内存的值一变,大家都会变。
3.实现深拷贝
1.通过JSON.parse( )和JSON.stringify( )
缺点非常明显,无法copy函数,undefined和symbol,同样也无法解决循环引用的对象。
2.以递归方式使用for in 方法来实现深拷贝
let obj = {name:{name:'1',id:[2,[3,4]]},id:[[1,2],[3,4]],son:undefined,sister:Symbol(1),fun:function(){return 1}}
const deepClone = (obj)=>{
let res = typeof obj==='obejct'?{}:[];
if(obj&&typeof obj ==='object'){
for(let key in obj){
if(obj[key]&& typeof obj[key]==='object'){
res[key] = deepClone(obj[key])
}else{
res[key] = obj[key];
}
}
}
return res;
}
let obj2 = deepClone(obj);
obj.name.name='2';
obj.id[0][0]=10;
console.log(obj2);