標籤:style class blog code java color
在JavaScript很多人複製一個對象的時候都是直接用"=",因為大家都覺得指令碼語言是沒有指標、引用、地址之類的,所以直接用"="就可以把一個對象複製給另外一個對象,如下代碼:
var i1 = 1; var i2 = i1; i2 = 2; alert("i1:"+i1+",i2:"+i2);
輸出結果:i1:1 , i2:2
但可能沒有發現,這種“複製”用在對象(object)類型是“錯誤”的,因為這隻是把對象的地址複製,所以如下代碼會進行了一次“錯誤”的複製:
代碼2
var o1 = {i : 1,s : "o1"}; var o2 = o1; o2.i=2; o2.s="o2"; alert("o1.i:"+o1.i+",o2.i:"+o2.i); alert("o1.s:"+o1.s+",o2.s:"+o2.s);
輸出:o1.i:2 , o2.i:2
o1.s:o2 , o2.s:o2
可能你會問為什麼 代碼1 可以複製,但 代碼2 卻沒有複製?
其實準確來說是“基礎資料型別 (Elementary Data Type)”可以複製,非基本類型(包括字串)只複製其引用。為什麼要這樣做呢?原因很簡單,為了減少開銷。大家都知道非基本類型有時候很大,如果重新開闢記憶體來存放一個這麼大的對象,開銷很大,導致運行會很慢。指令碼語言是直接在虛擬機器(或者瀏覽器)運行,它經過虛擬機器這一層來處理代碼,速度已經相對其他編譯語言慢很多,所以如果把非基本對象再做“複製”,那麼可能你要等上一年半載才能運行得了程式,因此只能複製對象的引用。
但很多時候我們並不希望函數去修改我們的這些對象參數,這就需要使用到對象的複製,我們應該對該對象做一個複製,然後操作這個複製的對象,這樣就不會影響我們的原對象了。 如果需要把整個對象複製,必須一個一個屬性或方法引用複製一偏,這樣為每個屬性開闢記憶體來存放你需要的資料,當然這樣相對來說會很慢,尤其資料量很多的時候, 在js中並沒有對象複製功能,因此需要我們自己實現,實現方法也不複雜,基本上是做一些屬性複製,我在網上找了一些,但有些實現並不好,如對於array對象複製後就成json對象了,並沒有保留原來的數組方式。不過最後還是找到了一個很好的複製函數,完美實現了js對象的複製功能,不論是Array對象或者是普通的Object,都可以很好的進行複製,這個函數使用constructor(函數構造器)進行複製。
方法一:
Object.prototype.Clone = function(){ var objClone; if (this.constructor == Object){ objClone = new this.constructor(); }else{ objClone = new this.constructor(this.valueOf()); } for(var key in this){ if ( objClone[key] != this[key] ){ if ( typeof(this[key]) == ‘object‘ ){ objClone[key] = this[key].Clone(); }else{ objClone[key] = this[key]; } } } objClone.toString = this.toString; objClone.valueOf = this.valueOf; return objClone; }
方法二:
function clone(obj){ var o; switch(typeof obj){ case ‘undefined‘: break; case ‘string‘ : o = obj + ‘‘;break; case ‘number‘ : o = obj - 0;break; case ‘boolean‘ : o = obj;break; case ‘object‘ : if(obj === null){ o = null; }else{ if(obj instanceof Array){ o = []; for(var i = 0, len = obj.length; i < len; i++){ o.push(clone(obj[i])); } }else{ o = {}; for(var k in obj){ o[k] = clone(obj[k]); } } } break; default: o = obj;break; } return o; }
方法三:
function clone3(obj){ function Clone(){} Clone.prototype = obj; var o = new Clone(); for(var a in o){ if(typeof o[a] == "object") { o[a] = clone3(o[a]); } } return o; }
方法四:
arrayObj=[1,2,3,4,5];
arrayObj.slice(0); //返回數組的拷貝數組,注意是一個新的數組,不是指向arrayObj.concat(); //返回數組的拷貝數組,注意是一個新的數組,不是指向