zoukankan      html  css  js  c++  java
  • javascript中的深度拷贝的实现过程及深拷贝的几种方法。

      对于浅拷贝和深拷贝的区别简单的说就是:浅复制会导致 obj 和 obj1 指向同一块内存地址,大概的示意图如下。而深复制一般都是开辟一块新的内存地址,将原对象的各个属性逐个复制出去。具体回答可参考https://www.zhihu.com/question/23031215  邹润阳的回答。

      这里主要讲的是深拷贝整个函数是怎么实现的。

    这里深拷贝的例子是参照妙味课堂上一节对象的引用中的,具体可以去妙味课堂看一下。

    <script>
    var obj1 = {
        a : { b : 10 }
    };
    
    /*function copy(obj){  //浅拷贝
        
        var newObj = {};
        
        for(var attr in obj){
            newObj[attr] = obj[attr];
        }
        
        return newObj;
        
    }*/
    
    function deepCopy(obj){  //深拷贝
        var newObj = {};
    
        if(typeof obj != 'object'){
            //console.trace();
            return obj;
        }
        
        for(var attr in obj){  
    
            newObj[attr] = deepCopy(obj[attr]); 
        }
        //console.trace();
        //console.log(newObj);
        return newObj;
    
        
    }
    
    var obj2 = deepCopy(obj1);//第一层循环为  obj2=deepCopy(obj1)----->newObj[a]=deepCopy(obj1[a])=deepCopy({b:10})------->newObj[a]=
                              //第二层循环为  newObj[b]=deepCopy({b:10}[b])=deepCopy(10)=10------->newObj[b]=10------->return newObj={b:10}
                              //newObj[a]={b:10}------>return newObj=a:{b:10}
    
    // obj2.a.b = 20;
    alert(obj2.a.b);     //10
    alert(obj1.a.b);  //10
    </script>
    View Code

    主要是用了递归的思想:

    obj2=deepCopy(obj1)----->调用deepCopy函数,传入的参数是obj1.第一个if判断是否是对象,如果是则执行下面的for/in循环,如果不是则返回obj。第一个obj1显然是对象,所以执行for/in循环。得到的结果是:

    1. newObj[a]=deepCopy(obj1[a])=deepCopy({b:10})----->再次调用deepCopy函数,传入的参数是对象{b:10},执行for/in循环。得到的结果是:
    2. newObj[b]=deepCopy({b:10}[b])=deepCopy(10)-------->再调用deepCopy函数,传入的参数是{10},不是对象,返回obj,也就是10,得到的结果是:
    3. newObj[b]=deepCopy({b:10}[b])=deepCopy(10)=10.

    至此,整个“递”的过程就完成了。下面是“归”的过程。也就是一个相反的过程

    1. deepCopy(10)=10.  代入上面的第二步,执行for/in循环得到newObj[b]=10,然后return newObj={b:10}
    2. 代入上面的第一步,执行for/in循环得到newObj[a]=deepCopy(obj1[a])=deepCopy({b:10})   deepCopy函数执行返回就是第一步的return newObj={b:10},所以newObj[a]={b:10},return newObj={a:{b:10}}

     在return newObj;上添加console.log(newObj);输出结果如下:

    可以看到的确是return了两次。第一次为{b:10},第二次为{a:{b:10}}.

    另一种实现是使用parse和stringify:

    var a = {
        name : { age : 100 }
    };
    
    var str = JSON.stringify(a);
    
    var b = JSON.parse(str);
    
    b.name.age = 200;
    
    alert( a.name.age ); //100
    View Code
    •如何其他浏览器做到兼容
    –http://www.json.org/去下载json2.js
    它能正确处理的对象只有 Number, String, Boolean, Array, 扁平对象,即那些能够被 json 直接表示的数据结构。
     

    努力但不功利~~!
  • 相关阅读:
    mysql 行号
    java 异常链
    springsecurity密码加密
    java 四舍五入
    ArrayList的使用及原理
    java 匿名内部类
    java 克隆
    logback的配置
    信号量 Semaphore
    障碍器 CyclicBarrier
  • 原文地址:https://www.cnblogs.com/langlang149/p/5825616.html
Copyright © 2011-2022 走看看