JS深拷貝繼承


所謂深拷貝,就是子對象不緊繼承父對象的非引用屬性,還能繼承父對象的引用屬性(Object,Array),當子對象對繼承的引用類型屬性做修改時,父對象的引用類型不會被修改。

我們先寫個淺拷貝的封裝函數:

 

function extendCopy(parent){
    var child={};
    for(var i in parent){
        child[i]=parent[i];
    }
    child.uber=parent;
    return child;
}

 

接下來寫個深拷貝的封裝函數:

 

function deepCopy(p,c){
    var c=c||{}; 
    for(var i in p){
        if(typeof p[i]==="object"){
            c[i]=(p[i].constructor===Array)? [] : {};
       deepCopy(p[i],c[i]); }
else{ c[i]=p[i]; } } return c; }


分析兩個函數有何不同,extendCopy方法是將父對象的屬性和方法逐個的拷貝給子對象,當遇到引用類型的屬性時,比如數組,那么若對子對象拷貝而來的數組進行重寫時,父對象對應的數組也會隨之改變,因為他們指向的是同一地址。

而deepCopy方法:

舉個栗子:

var parent={

  score:[1,2,3,4];

}

 

var child=deepCopy(parent);

執行deepCopy函數后,當執行到

if(typeof parent[score]==='object')時,

child[score]=[];

再執行deepCopy(parent[score],child[score]);

此時typeof p[i]就不是'object'類型了,而是number類型,

所以

child[score][1]=parent[score][1]=1;

child[score][2]=parent[score][2]=2;

child[score][3]=parent[score][3]=3;

child[score][4]=parent[score][4]=4;

在return child[score];

這樣就完成了深拷貝,child[score]和parent[score]不是指向同一個地址了。但此時兩者值相同,只是地址不同,若再對child[score]做修改,parent[score]不會有任何變化。

我們來試驗一下:

 

var Shape={
    color:"blue",
    name:"shape",
    size:[1,2,3,4],
    getName:function(){
        return this.name;
    }
}

    
    var circle=deepCopy(Shape); 
    var tran=extendCopy(Shape);
    circle.size.push(5,6);
    console.log(circle.size); //[1,2,3,4,5,6]
    console.log(Shape.size);//[1,2,3,4]  深拷貝父對象值沒有變化
    tran.size.push(5,6,7,8);
    console.log(circle.size); //[1,2,3,4,5,6]
    console.log(tran.size);//[1,2,3,4,5,6,7,8]
    console.log(Shape.size);    //[1,2,3,4,5,6,7,8] 淺拷貝隨着tran.size的改變,Shape.size也會隨之改變,

 

上述demo很好的驗證了淺拷貝和深拷貝的區別

 


免責聲明!

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



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