• 深度解析javascript中的浅复制和深复制


           在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型。我们都知道有Number,Boolean,String,Null,Undefined,Object五种类型。而Object又包含Function,Array和Object自身。前面的五种类型叫做基本类型,而Object是引用类型。可能有人就要问,为什么要分基本类型和引用类型呢?后面你就会明白的。

         我们首先来看看浅复制和深复制的简洁定义:

    • 深复制:直接将数据复制给对应的变量
    • 浅复制:将数据的地址复制给对应的变量

    而数据类型和我们要讨论的复制类型又有怎样的联系呢?我们试着摸索一下吧

    实验一:

    1 var a = "dengkunming";
    2 var a1 = a;
    3 alert(a1);//dengkunming
    4 a="abc";
    5 alert(a1);//dengkunming;

    这段代码中我们把a赋值给a1,当a的值改变时,a1没有发生变化。

    实验二:

    1 var a = [0,1,2,3];
    2 var a1= a;
    3 alert(a1);//[0,1,2,3]
    4 a[1]="变";
    5 alert(a1);//[0,"变",2,3]

    在这段代码中我们同样把a赋值给a1,当a的值改变的时候,a1却发生了变化。

         这是咋回事了,同样的操作其结果怎么会有差异了?我们回头看看,聪明的一休认为可能是这两个a有些不同。那些不同了?前面的是字符串,后面的数组。好像就是我们前面提到的基本类型和数据类型吧。那我们把数据类型换一下看看会有什么结果。

    实验三:

    1 var a = 3578;
    2 var a1 = a;
    3 alert(a1);//3578
    4 a=8735;
    5 alert(a1);//3578

    实验四:

    1 1 var a = {w1:2,w2:3}
    2 2 var a1= a;
    3 3 alert(a1);//{w1:2,w2:3}
    4 4 a1.w1="邓";
    5 5 alert(a);//{w1:"邓",w2:3}

        在这两组实验中,我们把数据类型分别换成了Number型和Object类型。实验三中可以发现a1不随a值的变化而变化,实验四中a会随着a1的变化而变化(这里和实验二略有不同,改变的是a1,当然你改变a的话,a1也会跟着变化)

       似乎我们可以得出个一般性的结论了:

        js中基本类型的赋值为深复制,而引用类型的赋值为浅复制。

       现在有必要把深复制和浅复制的定义扩展一下了。

    • 浅复制:就是把数据的地址赋值给对应变量,而没有把具体的数据复制给变量,变量会随数据值的变化而变化。
    • 深复制:就是把数据赋值给对应的变量,从而产生一个与源数据不相干的新数据(数据地址已变化)。

    实验五:

    1 var a = {w1:2,w2:3}
    2 var a1= a;
    3 alert(a1);//{w1:2,w2:3}
    4 var a={x1:7,x2:8}
    5 alert(a1);//{w1:2,w2:3}

         按照我们上面的理论来讲,这里是浅复制。a1应该随着a的变化而变化呀,可在这里为什么会事与愿违了?这就是引用类型惹的祸了。对象赋值其实都是引用传值,传递的是一个地址。那么实验五中的第四行其实就是把变量a指向了一个新的地址。而a1还是指向的原来那个地址,原来地址中的值没变,所以a1就不会变。所以请记住:浅复制不会随着存储数据地址的变化而变化,只会随着数据值的变化而变化。

         那我们如何实现引用类型的深度复制呢?这就是老话题深度克隆了。就是需要自己写一个非原生的clone函数喽。

     1 function clone(obj){
     2     var o=[]; 
     3     if(obj.constructor== Array) {
     4         o=obj.slice(0);
     5        }else{
     6            o={};
     7            for(var i in obj){
     8                 o[i] = typeof obj[i] === "object" ? obj[i].clone() : obj[i];} 
     9        }
    10        return o;
    11 
    12 }

        小可不才,文章中定会有所纰漏,望指出。也学一下大牛的语气,此文原创,转载请注明出处。如果你觉得文章还不错,就怒顶并推荐一下下吧!!!!

  • 相关阅读:
    redhat6.4 数据包无法到达
    hibernate-Table 'XXX.XXX' doesn't exist
    LeetCode 之 TwoSum
    vim 中的常用编辑
    linux sed 批量替换多个文件中的字符串
    RedHat 6.4企业版利用iso镜像做本地yum源
    win7 vmware虚拟机上网设置
    virtualbox ubuntu下ssh连接
    Source Insight 插件
    非递归排序
  • 原文地址:https://www.cnblogs.com/mingwaer/p/3739650.html
Copyright © 2020-2023  润新知