美文网首页
js引用类型深拷贝

js引用类型深拷贝

作者: usual2970 | 来源:发表于2017-03-30 16:46 被阅读0次

    一、js数据类型

    js的数据类型可以简单的概括为两大类:原始类型和引用类型。原始类型包括:Undefined、Null、Boolean、Number 和 String。引用类型通常包括:数组和对象。如下图:

    js数据类型

    二、各种类型的复制效果

    首先看看原始类型的复制:

    var a=12;
    var b=a;
    b=34;
    console.log(a) //12
    console.log(b) //34
    

    可以看出整数b从整数a复制而来,并且修改b并不会对a产生影响。
    实际上,系统新申请了一块内存供b使用。如果把变量比作房子,b房子就是按照a房子的样子新盖的,你装修b房子并不会影响a房子
    再看引用类型的拷贝

    var a=[1,2,3]
    var b=a
    b[1]=4
    console.log(a) //[1,4,3]
    console.log(b) //[1,4,3]
    

    可以看出同样数组b从数组a复制而来,修改了b导致a的内容也改变了。实际上a和b引用了同一块内存。如果也把变量比作房子,a和b实际上是同一座房子的钥匙,你装修了房子,如果装修的不好,别人可能会打你。
    以上情形就是浅拷贝,多数情况下,这并不是我们想要的结果。

    三、深拷贝的解决方案

    对于比较简单的数组,比如[1,2,3,4],可以使用slice,concat进行复制:

    var a=[1,2,3]
    var b=a.slice(0)
    b[1]=4
    
    var c=[2,3,4]
    var d=[].concat(c);
    d[1]=5
    console.log(a) //[1,2,3]
    console.log(b) //[1,4,3]
    
    console.log(c) //[2,3,4]
    console.log(d) //[2,5,4]
    

    但是对于比较复杂的数据结构就不那么管用了:

    var a=[1,{k1:2,k2:3,k3:4,children:[]},5]
    var b=a.slice(0)
    b[1].children[0]={a:1,b:2,c:3}
    console.log(a) //[1,{k1:2,k2:3,k3:4,children:[a:1,b:2,c:3]},5]
    console.log(b) //[1,{k1:2,k2:3,k3:4,children:[a:1,b:2,c:3]},5]
    

    网络上有人给出如下方法,其实并没有用

    function copyArr(arr){
            return arr.map((e)=>{
                if(typeof e === 'object'){
                    return Object.assign({},e)
                }else{
                    return e
                }
            })
        }
    

    当然了还可以找到能用的方法,但是都比较复杂,我这里提供一个比较简单不需要循环的方法,原理就是将对象或数组序列化成字符串,然后再解析成对象或数组:

    function copyArr(arr){
      return JSON.parse(JSON.stringify(arr))
    }
    
    

    相关文章

      网友评论

          本文标题:js引用类型深拷贝

          本文链接:https://www.haomeiwen.com/subject/ggcpottx.html