JavaScript 原型繼承
■知識點(diǎn)
原型繼承是一種簡化的繼承機(jī)制,也是JavaScript原生支持的繼承模式。在原型繼承中,類和實(shí)例概念被淡化了,一切都從對象的角度來考慮。原型繼承不再需要使用類來定義對象的結(jié)構(gòu),而是直接定義對象并被其他對象引用,這樣就形成了一種繼承關(guān)系,其中引用對象被稱為原型對象。JavaScript能夠根據(jù)原型鏈來查找對象之間的這種繼承關(guān)系。
■實(shí)例設(shè)計(jì)
下面使用原型繼承的方法設(shè)計(jì)類型繼承。
function A(x){ //A類
this.xl= x; //A的私有屬性xl
this.getl = function(){ //A的私有方法getl ()
return this.xl;
}
}
function B(x){ //B類
this.x2 = x; //B的私有屬性x2
this.get2 = function () { //B的私有方法get2()
return this.x2 + this.x2;
};
}
B.prototype = new A(1); //原型對象繼承A的實(shí)例
function C(x){ //C類
this. x3 = x; //C的私有屬性x3
this.get3 = function(){ //C的私有方法get3()
return this.x3 * this.x3;
};
}
C.prototype = new B(2); //原型對象繼承B的實(shí)例
在上面的示例中,分別定義了3個(gè)構(gòu)造函數(shù),然后通過原型鏈把它們串聯(lián)在一起,這樣C函數(shù)能夠繼承B函數(shù)和A函數(shù)的成員,而B函數(shù)能夠繼承A函數(shù)的成員。
Prototype的最大特點(diǎn)就是能夠允許對象實(shí)例共享原型對象的成員。因此如果把某個(gè)對象作為一個(gè)類型的原型,那么這個(gè)對象的類型也可以作為那些以這個(gè)對象為原型的實(shí)例的父類。
此時(shí),可以在C的實(shí)例中調(diào)用B和A的成員。
var b = new B(2); //實(shí)例化B
var c = new C(3); //實(shí)例化C
console.log(b.xl); //在實(shí)例對象b中調(diào)用A的屬性xl,返回1
console.log(c.xl); //在實(shí)例對象C中調(diào)用A的屬性xl,返回1
console.log(c.get3()); //在實(shí)例對象c中調(diào)用C的方法get3(),返回9
console.log(c.get2()); //在實(shí)例對象c中調(diào)用B的方法get2(),返回4
基于原型的編程是面向?qū)ο缶幊痰囊环N特定形式。在這種編程模型中,不需要聲明靜態(tài)類,而是通過復(fù)制己經(jīng)存在的原型對象來實(shí)現(xiàn)繼承關(guān)系。因此,基于原型的模型沒有類的概念,原型繼承中的類僅是一種模式,或者說是沿用面向?qū)ο缶幊痰母拍睢?/p>
■小結(jié)
原型繼承的優(yōu)點(diǎn)是結(jié)構(gòu)簡單,使用簡便,但是也存在以下幾個(gè)缺點(diǎn)。
每個(gè)類型只有一個(gè)原型,所以它不支持多重繼承。
不能友好地支持帶參數(shù)的父類。
a 使用不靈活。在原型聲明階段實(shí)例化父類,并把它作為當(dāng)前類型的原型,這限制了父類實(shí)例化
的靈活性,無法確定父類實(shí)例化的時(shí)機(jī)和場合。
^ prototype屬性固有的副作用。
點(diǎn)擊加載更多評論>>