Javascript对象浅拷贝和深拷贝

  

javascript 中的引用数据用赋值运算符进行赋值时

复制的是变量的引用地址 这就是我们所说的浅拷贝

当进行浅拷贝时,拷贝后的变量和被拷贝变量其实都是引用的是一个地址 

也就是说当一个改变时 另一个也会跟着改变

而在拷贝基本数据类型时 例如 numbar 整形时  拷贝的变量和被拷贝的变量没有直接关系,因为此时它们的拷贝是变量的值  

这是拷贝基本数据类型 此时拷贝的变量和被拷贝的变量两者之间没有直接关系,一个改变了,另一个不会跟着改变 

let a = 10;
b = a;

a = 100;

console.log(a);//100

console.log(b);//10

但是 当拷贝引用数据类型时 例如对象 此时问题就出来了,我们可以看到,其中一个改变 另一个也会跟着改变 

         let obj = {
             a:1,
             b:2
         };

         let copy = obj;
         console.log(copy,obj);//{a: 1, b: 2} {a: 1, b: 2}

         copy.a = 100;
         console.log(copy,obj);//{a: 100, b: 2} {a: 100, b: 2}

 

方法一

当然我们可以对他进行深度拷贝

方法是循环遍历原始对象,然后一个接一个地复制每个属性

        function copyo(obj){
              let copyobj = {};
              let key = "";
              for(key in obj){
                  copyobj[key] = obj[key];
              }
              return copyobj;
          }
          let obj2 = {
              a:100,
              b:{
                  a:10,
                  b:10
              }
          }

          let copyobj2 = copyo(obj2);

          obj2.a = 1000;

          console.log(obj2.a,copyobj2.a);//1000 100
          /* 以上方法实现了一个基本的深度拷贝 我们可以发现 更改另一个值时 拷贝的变量并没有跟着改变*/

          /* 
            但这个方法存在弊端 我们可以看到 当对象中的某个成员的也是一个对象时 这个方法就不管用了 
            虽然我们可以对方法进行改造 但这并没有什么大用 他并没有从根本上解决这个问题
          */
          obj2.b["a"] = 2000;
          console.log(obj2.b["a"],copyobj2.b["a"]);//2000 2000

方法二

我们可以使用js提供的Object.assign()这个方法来复制一个对象

        let obj3 = {
                a: 1,
                b: 2,
                c:{
                    a:200
                }
           }
           let copyobj3 = Object.assign({},obj3);
           obj3.a = 99;
           console.log(obj3.a,copyobj3.a);//99 1

看起来这个js提供的方法的确是深度拷贝了一个对象

但是 它和上面编写的copyo方法有同样的错误

但对象的某个成员也是对象时 它只会复制其引用地址

所以这个Object.assign方法也不能完全深度拷贝

obj3.c["a"] = 20000;
console.log(obj3.c["a"],copyobj3.c["a"]);//20000 20000

 

 

完全深度拷贝

          //下面给出完全深度拷贝的方案
           //就是利用 JSON.parse 和 JSON.stringify 方法来实现完全深度拷贝
           let obj4 = {
                a: 1,
                b: 2,
                c:{
                    a:200
                }
           }
           let copyobj4 = JSON.parse(JSON.stringify(obj4));
           obj4.a = 100;
           obj4.c["a"]=20000;
           console.log(obj4.a,obj4.c["a"]);//100 20000
           console.log(copyobj4.a,copyobj4.c["a"]);//1 200
           //这样就实现了完全深度拷贝

但是它也有弊端 当对象的某个成员是方法时 它将不会被拷贝

           let obj5 = {
                a: 1,
                b: 2,
                c:{
                    a:200
                },
                d:function(){
                    return 123;
                }
           }
           let copyobj5 = JSON.parse(JSON.stringify(obj5));
           console.log(obj5,copyobj5);
           /* '
            分别输出如下
            obj5:
            {
                a: 1,
                b: 2,
                c:{
                    a:200
                },
                d:function(){
                    return 123;
                } 
            }

            copyobj5:
            {
                a: 1,
                b: 2,
                c:{
                    a:200
                }
            }
            */

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值