JS對象復制


     在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 卻沒有復制?
    其實准確來說是“基本數據類型”可以復制,非基本類型(包括字符串)只復制其引用。為什么要這樣做呢?原因很簡單,為了減少開銷。大家都知道非基本類型有時候很大,如果重新開辟內存來存放一個這么大的對象,開銷很大,導致運行會很慢。腳本語言是直接在虛擬機(或者瀏覽器)運行,它經過虛擬機這一層來處理代碼,速度已經相對其他編譯語言慢很多,所以如果把非基本對象再做“復制”,那么可能你要等上一年半載才能運行得了程序,因此只能復制對象的引用。

     但很多時候我們並不希望函數去修改我們的這些對象參數,這就需要使用到對象的克隆,我們應該對該對象做一個克隆,然后操作這個克隆的對象,這樣就不會影響我們的原對象了。 如果需要把整個對象復制,必須一個一個屬性或方法引用復制一偏,這樣為每個屬性開辟內存來存放你需要的數據,當然這樣相對來說會很慢,尤其數據量很多的時候, 在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(); //返回數組的拷貝數組,注意是一個新的數組,不是指向

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM