讀古今文學網 > 編寫高質量代碼:改善JavaScript程序的188個建議 > 建議92:不建議使用原型繼承 >

建議92:不建議使用原型繼承

原型繼承是一種簡化的繼承機制,也是目前最流行的一種JavaScript繼承方式。實際上JavaScript就是一種基於原型的語言。在原型繼承中,類和實例概念被淡化了,一切都從對象的角度來考慮。

但是,原型繼承就不再需要使用類來定義對象的結構,直接定義對象,該對像被其他對像引用,這樣就形成了一種繼承關係,其中引用對像稱為原型對像(prototype object)。JavaScript能夠根據原型鏈來查找對象之間的這種繼承關係。下面就是一個簡單的原型繼承示例:


function A(x){//A類

this.x1=x;

this.get1=function{

return this.x1;

}

}

function B(x){//B類

this.x2=x;

this.get2=function{

return this.x2+this.x2;

};

}

B.prototype=new A(1);//用原型對像繼承A的實例

function C(x){//C類

this.x3=x;

this.get3=function{

return this.x2*this.x2;

};

}

C.prototype=new B(2);//用原型對像繼承B的實例


在上面示例中,分別定義了3個函數,然後通過原型繼承方法把它們連在一起,這樣C能夠繼承B和A的成員,B能夠繼承A的成員。prototype的最大特點就是能夠允許對像實例共享原型對象的成員。因此,如果把某個對象作為一個類型的原型,那麼就可以說這個類型的實例以這個對象為原型。實際上此時這個對象的類型也可以作為那些以這個對象為原型的實例的類型。此時,可以在C的實例中調用B和A的成員:


var b=new B(2);

var c=new C(3);

alert(b.x1);//在實例對像b中調用A的屬性x1,返回1

alert(c.x1);//在實例對像c中調用A的屬性x1,返回1

alert(c.get3);//在實例對像c中調用C的方法get3,返回9

alert(c.get2);//在實例對像c中調用B的方法get2,返回4


基於原型的編程是面向對像編程的一種特定形式。在這種編程模型中,不需要聲明靜態類,而可以通過複製已經存在的原型對像來實現繼承關係。因此,基於原型的模型沒有類的概念,原型繼承中的類僅是一種模擬。原型繼承非常簡單,其優點是結構簡單,不需要每次構造函數都調用父類的構造函數,並且不需要通過複製屬性的方式就能快速地實現繼承。但它也存在以下幾個缺點:

❑由於每個類型只有一個原型,因此它不直接支持多重繼承。

❑不能很好地支持多參數或動態參數的父類。在原型繼承階段,用戶還不能決定以什麼參數來實例化構造函數。

❑使用不夠靈活。用戶需要在原型聲明階段實例化父類對象,並且把它作為當前類型的原型,這會限制父類實例化的靈活性,很多時候無法確定父類對像實例化的時機和場合。