zoukankan      html  css  js  c++  java
  • 谈谈JavaScript深浅拷贝

    浅拷贝

     1 function shallowCopy(source){ 
     2 
     3      var newObj = {};
     4 
     5      for(var attr in source){
     6      newObj[attr] = source[attr];
     7      }
     8 
     9      return newObj;
    10 
    11      }

    一般简单的对象用浅拷贝就行了,深拷贝是对付哪种对象中还有对象的类型。

    深拷贝

     1 function deepCopy(source){  
     2         var newObj = {};
     3 
     4         if(typeof source != 'object'){
     5             //console.trace();
     6             return source;
     7         }
     8 
     9         for(var attr in source){
    10 
    11             newObj[attr] = deepCopy(source[attr]);
    12         }
    13         //console.trace();
    14         //console.log(newObj);
    15         return newObj;
    16 
    17 
    18     }
    19     var obj1 = {
    20         a : { b : 10 }
    21     };
    22     var obj2 = deepCopy(obj1);//第一层循环为  obj2=deepCopy(obj1)----->newObj[a]=deepCopy(obj1[a])=deepCopy({b:10})------->newObj[a]=
    23                               //第二层循环为  newObj[b]=deepCopy({b:10}[b])=deepCopy(10)=10------->newObj[b]=10------->return newObj={b:10}
    24                               //newObj[a]={b:10}------>return newObj=a:{b:10}
    25 
    26     // obj2.a.b = 20;
    27     alert(obj2.a.b);     //10
    28     alert(obj1.a.b);  //10
    29     console.log(obj1,obj2)

    主要是用了递归的思想:

    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:

     1 var a = {
     2     name : { age : 100 }
     3 };
     4 
     5 var str = JSON.stringify(a);
     6 
     7 var b = JSON.parse(str);
     8 
     9 b.name.age = 200;
    10 
    11 alert( a.name.age ); //100

    它能正确处理的对象只有 Number, String, Boolean, Array, 扁平对象,即那些能够被 json 直接表示的数据结构。

  • 相关阅读:
    Go 语言简介(下)— 特性
    Array.length vs Array.prototype.length
    【转】javascript Object使用Array的方法
    【转】大话程序猿眼里的高并发架构
    【转】The magic behind array length property
    【转】Build Your own Simplified AngularJS in 200 Lines of JavaScript
    【转】在 2016 年做 PHP 开发是一种什么样的体验?(一)
    【转】大话程序猿眼里的高并发
    php通过token验证表单重复提交
    windows 杀进程软件
  • 原文地址:https://www.cnblogs.com/it-Ren/p/10551785.html
Copyright © 2011-2022 走看看