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

  • 相关阅读:
    POJ 3253 Fence Repair
    POJ 2431 Expedition
    NYOJ 269 VF
    NYOJ 456 邮票分你一半
    划分数问题 DP
    HDU 1253 胜利大逃亡
    NYOJ 294 Bot Trust
    NYOJ 36 最长公共子序列
    HDU 1555 How many days?
    01背包 (大数据)
  • 原文地址:https://www.cnblogs.com/lzpong/p/6973003.html
Copyright © 2011-2022 走看看