zoukankan      html  css  js  c++  java
  • JavaScript 中的对象深度复制(Object Deep Clone)

    JavaScript中并没有直接提供对象复制(Object Clone)的方法。

    JavaScript中的赋值,其实并不是复制对象,而是类似`c/c++`中的引用(或指针),因此下面的代码中改变对象b中的元素的时候,也就改变了对象a中的元素。

    a = {k1:1, k2:2, k3:3};
    b = a;
    b.k2 = 4;

    如果只想改变b而保持a不变,就需要对对象a进行复制。

    用jQuery进行对象复制

    在可以使用jQuery的情况下,jQuery自带的extend方法可以用来实现对象的复制。

    a = {k1:1, k2:2, k3:3};
    b = {};
    $.extend(b,a);

    自定义clone()方法来实现对象复制

    1.下面的方法,是给Object的原型(prototype)添加深度复制方法(deep clone)。

     1 Object.prototype.clone = function() {
     2     // Handle null or undefined or function
     3     if (null == this || "object" != typeof this)
     4         return this;
     5     // Handle the 3 simple types, Number and String and Boolean
     6     if(this instanceof Number || this instanceof String || this instanceof Boolean)
     7         return this.valueOf();
     8     // Handle Date
     9     if (this instanceof Date) {
    10         var copy = new Date();
    11         copy.setTime(this.getTime());
    12         return copy;
    13     }
    14     // Handle Array or Object
    15     if (this instanceof Object || this instanceof Array) {
    16         var copy = (this instanceof Array)?[]:{};
    17         for (var attr in this) {
    18             if (this.hasOwnProperty(attr))
    19                 copy[attr] = this[attr]?this[attr].clone():this[attr];
    20         }
    21         return copy;
    22     }
    23     throw new Error("Unable to clone obj! Its type isn't supported.");
    24 }

    所有对象可以直接使用`.clone()`

    var a=[1,2,true,null,"fdsfdsa",[1,"fdsa",{"a":1,"b":["fd",3,{"b":"3","c":""},new Date()],"c":new Date(),"d":false,"e":null}]];
    var b=a.clone();

    2.使用额外的工具函数实现,适用于大部分对象的深度复制(Deep Clone)。

     1 function clone(obj) {
     2     // Handle the 3 simple types, and null or undefined or function
     3     if (null == obj || "object" != typeof obj) return obj;
     4 
     5     // Handle Date
     6     if (obj instanceof Date) {
     7         var copy = new Date();
     8         copy.setTime(obj.getTime());
     9         return copy;
    10     }
    11     // Handle Array or Object
    12     if (obj instanceof Array | obj instanceof Object) {
    13         var copy = (obj instanceof Array)?[]:{};
    14         for (var attr in obj) {
    15             if (obj.hasOwnProperty(attr))
    16               copy[attr] = clone(obj[attr]);
    17         }
    18         return copy;
    19     }
    20     throw new Error("Unable to clone obj! Its type isn't supported.");
    21 }

    用法类似:

    var a=[1,2,true,null,"fdsfdsa",[1,"fdsa",{"a":1,"b":["fd",3,{"b":"3","c":""},new Date()],"c":new Date(),"d":false,"e":null}]];
    var b=clone(a);

    测试

    用上面两种方法都可以得到同样的结果。
    至于用哪个怎么用,取决于你的喜好/习惯了 :)     就本人来说,我更倾向于使用原型的方法啦,方便嘛,啊哈哈哈~
    你想测试结果的话,直接复制代码运行:

     1 var a=[1,2,true,null,"fdsfdsa",[1,"fdsa",{"a":1,"b":["fd",3,undefined,{"b":"3","c":""},new Date()],"c":new Date(),"d":false,"e":null,"f":function(){return 2;}}],function(){}];
     2 console.log("a=",a);
     3 console.log("b=a.clone();");
     4 b=a.clone();
     5 console.log("JSON.stringify(a)==JSON.stringify(b) = ",JSON.stringify(a)==JSON.stringify(b));
     6 console.log("JSON.stringify(a)===JSON.stringify(b) = ",JSON.stringify(a)===JSON.stringify(b));
     7 console.log("JSON.stringify(a) = ",JSON.stringify(a));
     8 console.log("JSON.stringify(b) = ",JSON.stringify(b));
     9 console.log("a[2]=123,b[2]=55555");
    10 a[2]=123,b[2]=55555;
    11 console.log("a=",a,"		","b=",b);
    12 
    13 console.log("b=clone(a);");
    14 b=clone(a);
    15 console.log("JSON.stringify(a)==JSON.stringify(b) = ",JSON.stringify(a)==JSON.stringify(b));
    16 console.log("JSON.stringify(a)===JSON.stringify(b) = ",JSON.stringify(a)===JSON.stringify(b));
    17 console.log("JSON.stringify(a) = ",JSON.stringify(a));
    18 console.log("JSON.stringify(b) = ",JSON.stringify(b));
    19 console.log("a[2]=1234,b[2]=33333");
    20 a[2]=1234,b[2]=33333;
    21 console.log("a=",a,"		","b=",b);

    可以看到, 输出结果 `a` 和 `b` 是相等的,但是 改变 `a` 的元素的值, 并不会影响到 `b` 的元素。

    访问Github,get更多技能:https://github.com/lzpong/H5_JS_Tools

  • 相关阅读:
    第三章 学习ICE 3.0Slice语言
    腾讯
    Websvn的安装
    fedora下装eclipse
    linux快捷键
    windows下SVN解决方案
    用ICE实现一个简单的聊天室
    Tortoise SVN 客户端使用方法
    GCC安装
    在VC++6.0 IDE中配置ICE工程[ ICE FOR VC++6.0 ]
  • 原文地址:https://www.cnblogs.com/lzpong/p/6973003.html
Copyright © 2011-2022 走看看