許多OO語言支持兩種繼承:介面繼承和實現繼承。ECMAScript只支持實現繼承,且繼承實現主要依賴原型鏈實現。 原型鏈 基本思想:利用原型讓一個引用類型繼承另一個引用類型的屬性和方法。 構造函數、原型和實例的關係:每個構造函數均有一個原型對象,原型對象均包含一個指向構造函數的指針,實例均包含一個指 ...
許多OO語言支持兩種繼承:介面繼承和實現繼承。ECMAScript只支持實現繼承,且繼承實現主要依賴原型鏈實現。
原型鏈
基本思想:利用原型讓一個引用類型繼承另一個引用類型的屬性和方法。
構造函數、原型和實例的關係:每個構造函數均有一個原型對象,原型對象均包含一個指向構造函數的指針,實例均包含一個指向原型對象的內部指針。若讓原型對象等於另一個類型的實例,此時原型對象將包含一個指向 另一個原型的指針,相應地,另一個原型中也包含一個指向另一個構造函數的指針。若另一個原型又是另一個類型的實例,那麼上述關係依然成立,如此層層遞進,就構成了實例與原型的鏈條。
原型鏈基本模式,示例代碼如下:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>原型鏈-繼承</title> 5 <script type="text/javascript"> 6 function Supertype(){ 7 this.property=true;//propertype屬於Supertype實例屬性 8 } 9 10 Supertype.prototype.getSuperValue=function(){//getSuperValue()屬於原型方法 11 return this.property; 12 };//至此,Supertype原型包含指向Supertype構造函數的constructor屬性和getSuperValue()方法。 13 14 function Subtype(){ 15 this.subproperty=false;//subproperty屬於Subtype實例屬性 16 } 17 18 //繼承了Supertype,重寫了原型對象 19 Subtype.prototype=new Supertype(); 20 21 //添加新方法 22 Subtype.prototype.getSubValue=function(){//為Subtype原型添加方法getSubValue() 23 return this.subproperty; 24 }//至此,Subtype原型模型中包含屬性和方法為:內部屬性[prototype]、property屬性、getSuperValue()方法。作為一個Supertype類型的實例,其內部屬性[prototype]指向Supertype原型,實例屬性property。 25 26 //重寫超類中的方法,因此需要謹慎地定義方法 27 Subtype.prototype.getSuperValue=function(){ 28 return false; 29 } 30 31 var instance=new Subtype();//實例內部屬性[prototype]指向Subtype原型;且包含實例屬性subproperty 32 alert(instance.getSuperValue());//在重寫超類函數之前返回true;重寫了超累函數之後返回false 33 34 //確定原型和實例的關係 35 alert(instance instanceof Object);//true 36 alert(instance instanceof Supertype);//true 37 alert(instance instanceof Subtype);//true 38 39 alert(Object.prototype.isPrototypeOf(instance));//true 40 alert(Supertype.prototype.isPrototypeOf(instance));//true 41 alert(Subtype.prototype.isPrototypeOf(instance));//true 42 </script> 43 </head> 44 <body> 45 </body> 46 </html>
原型鏈的問題:
(1)原型鏈子類實例共用父類引用類型,同原型模型的問題一樣。
(2)在創建子類的實例時,不能在不影響所有對象實例的情況下,向超類型的構造函數傳遞參數
因此,實踐中很少單獨使用原型鏈。
文章內容部分摘自《JavaScript高級程式設計(第3版)》