一.浅拷贝和深拷贝是什么?
拷贝即为复制,我们一般通过赋值的方式可以进行拷贝一个变量的值。
例如:
当复制基本数据类型是
let a = 23;
let b = a;
b = 24;
console.log(a);
console.log(b);控制台将会输出如下:

但是当我们复制引用数据类型时
let a = {name:"zhangjie"}
let b = a;
b.name = "zhangsan";
console.log(a);
console.log(b);
你会发现两者有点不同,在进行引用数据类型赋值时,当修改一个变量的值,另外一个变量的值也改变了。因为在赋值时引用数据类型复制的是地址值,假设这里的变量a的地址值为ox123,那么b复制到的只是a的地址值ox123。此时a、b指向同一块内存地址。当b的name属性值变化时,a也会一起变化。在开发中我们是不希望遇到的。存在数据的安全问题。
浅拷贝和深拷贝正是为了解决这样的问题。
浅拷贝笔者认为它只是解决了第一层拷贝问题
例如:
let a = {name:"zhangjie"}
let b = Clone.Sclone(a);
b.name = "zhangsan";
console.log(a);
console.log(b);当进行进行浅拷贝后

此时b的改变并没有影响到a的改变。其中Clone.Sclone()为手写的浅拷贝函数。
但是如果拷贝的是这样的
let a = {name:"zhangjie",like:{ game:"wangzhe",}}
let b = Clone.Sclone(a);
b.like.game = "chiji";
console.log(a);console.log(b);
此时你发现浅拷贝就不起作用了。这个时候就应该用深拷贝了。
二.手写代码
1.浅拷贝
let Sclone =(obj)=>{
// 方法一
// let obj1 = {}
// obj1 = Object.assign({},obj)
// 方法二
let obj1 ={...obj}
return obj1
}正如代码中浅拷贝的自定义函数有两种,一种是用Object.assign解决,一种是采用...运算符。
如果拷贝的是数组的话
let Sclone =(obj)=>{
// 方法一 let obj1 = [];
obj1 = Object.assign([],obj)
// 方法二
// let obj1 =[...obj]
return obj1
}写通用的方法的话,自己可以下来写,笔者就不给出了。
2.深拷贝(重点)
let Dclone = (obj)=>{
function getObjclass(obj){
// 判断数据类型
let result = Object.prototype.toString.call(obj).slice(8,-1);
return result;
}
let result;
let objclass = getObjclass(obj);
console.log(objclass);
if(objclass === "Object")
{
result = {};
}
else if(objclass === "Array"){
result = [];
}else{
return obj;
}
for(let key in obj)
{
let value = obj[key];
// 递归取数据
if(getObjclass(value) === "Object"||"Array")
{
result[key] = Dclone(value);
}else{
result[key] = value;;
}
}
return result;
}解决问题类型
let a = [1,{name:"zhangjie"}]
let b = Clone.Dclone(a);
b[1].name = "zhangsan";
console.log(a);console.log(b);
此时发现第二层的b拷贝也不会影响到a了,当然深拷贝是针对多层的。读者下来可以试一试。
欢迎大家留言,给出自己的看法,或者指出我的错误。