转载来源:搬砖猴哥
我们先来说一下浅拷贝:
var obj = {a:1};
var b = obj;
console.log(b)
// 输出结果为1
但是浅拷贝会存在一个问题,通过浅拷贝拷贝了一个引用类型,如果我们去修改obj会怎么样?
var obj = {
a:1
};
var b = obj;
// 修改obj里面的a属性
obj.a = 2
console.log(b)
// 输出结果 {a:2}
再来看下一个问题,如果obj里面又包含了一个c对象,然后修改c会怎么样?
var obj = {
a:1,
c:{
c1:1
}
};
var b = {}
for(key in obj){
b[key] = obj[key]
}
// 修改 obj的属性
obj.c.c1 = 2
console.log(b)
// 输出结果为 {a:1,c:{c1:2}}
当我们修改了obj里面的c对象的时候,b里面的c也跟着变化了,原因就是,b里面拷贝的c也是一个引用类型,从而拷贝的只是一个地址,并且还有一个问题,就是我们不知道obj里面有多少层,可能c1里面又包含一个引用类型,并且我们不知道引用类型是对象还是数组,那么我们就要解决这个问题,这样的问题就是深拷贝。
我们可以先利用一个简单方式来实现深拷贝:
var obj = {
a:1,
c:{
c1:1,
c2:2
}
};
var str = JSON.stringify(obj)
var b = JSON.parse(str)
// 修改 obj的属性
obj.c.c1 = 2
console.log(b)
我们先将需要拷贝的代码利用JSON.stringify转成字符转,然后再利用JSON.parse将字符转转回对象,即完成拷贝。
也可以利用递归实现拷贝:思路;
1.我们肯定要定义一个方法,那么这个方法最终应该返回一个深拷贝的数据
2.既然要返回一个数据,我们首先就要定义一个数据,但是数据是对象还是数组?所以需要判断,如果要拷贝的数据是数组,即定义一个数组,如果是一个对象,即定义一个对象
3.方法里面怎么拷贝啊?还是一样的利用for in 循环,在循环内部,需要判断,如果是类型是简单类型,直接拷贝,如果是引用类型,就需要在一次的将引用类型里面的值取出来
var obj = {
a:1,
c:{
c1:1,
c2:2
}
};
function deepCopy(obj){
// 判断拷贝的数据是对象还是数组 生成定义的数据
var copy = Array.isArray(obj)? []:{}
for(key in obj){
// 循环的时候如果此项为引用类型,需要 在一次的将引用类型里面的值取出来
if(typeof obj[key] == 'object'){
// 再次调用该方法取数据
copy[key] = deepCopy(obj[key])
}else{
copy[key] = obj[key]
}
}
return copy
}
var b = deepCopy(obj)
console.log(b)
———————————
版权声明:本文为CSDN博主「搬砖猴哥」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_41819098/article/details/88777797