JavaScript 中的對象深度複製(Object Deep Clone)

 

JavaScript中並沒有直接提供對象複製(Object Clone)的方法。

JavaScript中的賦值,其實並非複製對象,而是相似`c/c++`中的引用(或指針),所以下面的代碼中改變對象b中的元素的時候,也就改變了對象a中的元素。c++

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

 

若是隻想改變b而保持a不變,就須要對對象a進行復制。git

用jQuery進行對象複製

在能夠使用jQuery的狀況下,jQuery自帶的extend方法能夠用來實現對象的複製。github

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,"\t\t","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,"\t\t","b=",b);

 

能夠看到, 輸出結果 `a` 和 `b` 是相等的,可是 改變 `a` 的元素的值, 並不會影響到 `b` 的元素。this

訪問Github,get更多技能:https://github.com/lzpong/H5_JS_Toolsspa

相關文章
相關標籤/搜索