zoukankan      html  css  js  c++  java
  • js对象简单、深度克隆(复制)

    javascript的一切实例都是对象,只是对象之间稍有不同,分为原始类型和合成类型。原始类型对象指的是字符串(String)、数值(Number)、布尔值(Boolean),合成类型对象指的是数组(Array)、对象(Object)、函数(Function)。

    既然对象分为这两类,他们之间的最大差别是复制克隆的差别。普通对象存储的是对象的实际数据,而引用对象存储的是对象的引用地址,而把对象的实际内容单独存放,因为引用对象通常比较庞大,这是数据开销和内存开销优化的手段。通常初学者很难理解这部分内容,就像对象的原型一样,也是同一个概念。对象的原型也是引用对象,把原型的方法和属性放在单独内存当中,而对象的原型链则指向这个内存地址。尽管这部分内容比较拗口复杂,那其中的原理都是一致的,目的也一致。

    1、原始类型对象的克隆

    1.1、字符串的克隆

    1. var x="1";
    2. var y=x;
    3. y="2";
    4. // "1"
    5. alert(x);
    6. // "2"
    7. alert(y);

    1.2、数值的克隆

    1. var x=1;
    2. var y=x;
    3. y=2;
    4. // 1
    5. alert(x);
    6. // 2
    7. alert(y);

    1.3、布尔值的克隆

    1. var x=true;
    2. var y=x;
    3. y=false;
    4. // true
    5. alert(x);
    6. // false
    7. alert(y);

    2、合成类型对象的克隆

    2.1、数组的克隆

    如果采用普通克隆:

    1. var x=[1,2];
    2. var y=x;
    3. y.push(3);
    4. // 1,2,3
    5. alert(x);
    6. // 1,2,3
    7. alert(y);

    由上可知,原始数组x,克隆数组y,修改了克隆数组y,但也同时修改了原始数组x,这就是引用对象的特点。那么如何才能达到完整的数组克隆呢?

    1. var x=[1,2];
    2. var y=[];
    3. var i=0;
    4. var j=x.length;
    5. for(;i<j;i++)
    6. {
    7. y[i]=x[i];
    8. }
    9. y.push(3);
    10. // 1,2
    11. alert(x);
    12. // 1,2,3
    13. alert(y);

    这样,克隆数组y,原始数组x,两个数组互补干扰,实现了完整的数组克隆。

    2.2、对象的克隆

    和数组的克隆同理,对象的完整克隆如下:

    1. var x={1:2,3:4};
    2. var y={};
    3. var i;
    4. for(i in x)
    5. {
    6. y[i]=x[i];
    7. }
    8. y[5]=6;
    9. // Object {1: 2, 3: 4}
    10. console.log(x);
    11. // Object {1: 2, 3: 4, 5: 6}
    12. console.log(y);

    2.3、函数的克隆

    var x=function(){alert(1);};
    var y=x;
    y=function(){alert(2);};
    
    // function(){alert(1);};
    alert(x);
    
    // y=function(){alert(2);};
    alert(y);

    函数的克隆,使用“=”符号就可以了,并且在改变克隆后的对象,不会影响克隆之前的对象,因为克隆之后的对象会单独复制一次并存储实际数据的,是真实的克隆。

    3、完整的对象克隆

    根据1和2,总结一下完整的对象克隆,包括克隆普通对象、引用对象。在写这个方法之前,我们必须想到的是,克隆引用对象必须采用完整克隆(深度克隆),包括对象的值也是一个对象也要进行完整克隆(深度克隆)。

    完整的对象克隆又称为深度对象克隆、对象的深度克隆、对象的深度复制等等。

    1. function clone(obj)
    2. {
    3. var o,i,j,k;
    4. if(typeof(obj)!="object" || obj===null)return obj;
    5. if(obj instanceof(Array))
    6. {
    7. o=[];
    8. i=0;j=obj.length;
    9. for(;i<j;i++)
    10. {
    11. if(typeof(obj[i])=="object" && obj[i]!=null)
    12. {
    13. o[i]=arguments.callee(obj[i]);
    14. }
    15. else
    16. {
    17. o[i]=obj[i];
    18. }
    19. }
    20. }
    21. else
    22. {
    23. o={};
    24. for(i in obj)
    25. {
    26. if(typeof(obj[i])=="object" && obj[i]!=null)
    27. {
    28. o[i]=arguments.callee(obj[i]);
    29. }
    30. else
    31. {
    32. o[i]=obj[i];
    33. }
    34. }
    35. }
    36. return o;
    37. }

    4、参考资料

  • 相关阅读:
    mount 和 umount 命令
    mmap函数使用
    Linux系统下查看目录大小
    守护进程的创建方法和步骤
    linux中的dup()系统调用
    uboot烧写命令--yaffs、jiffs和ubifs
    对volatile关键字的理解
    linux下如何挂接(mount)光盘镜像文件、移动硬盘、U盘、Windows网络共享和NFS网络共享
    常用NFS mount选项介绍
    mount nfs 经常出错信息总结(转)
  • 原文地址:https://www.cnblogs.com/autismtune/p/5203801.html
Copyright © 2011-2022 走看看