js 深拷贝一个对象、数组、多维数组拷贝

330 阅读2分钟

首先拷贝分为浅拷贝和深拷贝

  • 浅拷贝 浅拷贝只复制某个对象的引用,而不复制对象本身,新旧对象还是共享同一块内存。 内存里的数据实体为同一个,好比给张三取个外号叫小三,实际是同一个人。
    let obj = {name:"张三",age:20,sex:"男"}
    let obj1 = obj;

    obj1.name="李四";
    console.log(obj);//{name:"李四",age:20,sex:"男"}
    console.log(obj1);//{name:"李四",age:20,sex:"男"}
  • 深拷贝 深拷贝会重新占用一块新的内存并创建一个一样的对象,新对象和原对象不共享内存,修改新对象不会改变原对对象,互不影响。
let obj={a:1,b:2}
let obj1 = Object.assign({},obj)
obj1.a = 11
obj1.b = 12
console.info(obj)
console.info(obj1)
输出结果:
{a:1,b:2}
{a:11,b:12}
这时候我们修改obj1的任何属性值都不影响原来obj的属性值

上面是对象只有一层的情况下,通过对象的合并产生一个新的对象,算完成了深拷贝,但是在实际开发过程中,经常是一个对象内包含其他对象,两层甚至三层四层的包裹着。这个时候再单纯的使用Object的assign去拷贝就行不通了

如果对象是多层的话
        var obj = {a:1,b:2c:{d:3,e:4,f:5}};

        var obj1 = Object.assign({},obj);
        obj1.b = 12;
        obj1.c.d = 13;
        console.log(obj);//{a:1,b:2,c:{d:13,e:4,f:5}};
        console.log(obj1);//{a:1,b:12,c:{d:13,e:4,f:5}};
###### 这时候对于obj对象来说是完成了深拷贝,修改a\b的值都没有问题
###### 但是注意c的值,我们拷贝的是obj对象Object.assign({},obj)
###### 在对象obj和obj1中c的值都是存的是对象{d:3,e:4,f:5}的地址值
###### 此时通过 obj1.c.d来修改实际上并没有修改obj1的属性c的值
###### 修改的是c的值对应的对象{d:3,e:4,f:5}的属性值
###### 这时候要修改obj1.c的值,应该直接赋值给c ,赋值可以是对象、数字、字符串等任何值
        obj1.c = {a1:1,b1:2,c1:3};
        console.log(obj);//{a:1,b:2,c:{d:13,e:4,f:5}};
        console.log(obj1);//{a:1,b:12,c:{a1:1,b1:2,c1:3}};
        obj1.c = 13;
        console.log(obj);//{a:1,b:2,c:{d:13,e:4,f:5}};
        console.log(obj1);//{a:1,b:12,c:13};

哈哈,此时对于obj而言是深拷贝,但是对于obj的c属性来说是浅拷贝,因为我们只是在完成obj的深拷贝的时候,把obj.c对应的地址值给复制了到了obj1.c。