這次延續上次的 prototype,稍微討論一下 prototype chain。這也是 JavaScript很特別的繼承方式下的方法。我參照 Professional JavaScript for Web Developers - Nicholas C. Zakas的 prototype chain的範例實作以及圖片說明如下。
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function (){
return this.property;
};
function SubType() {
this.subproperty = false;
}
//inherit from SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function () {
return this.subproperty;
};
var instance = new SubType();
window.console.log(instance.getSuperValue());
Check out this Pen!
我們有兩個類別 SuperType以及 SubType,都各自有其屬性跟方法。其差別在於 SubType有新增一個 SuperType的 instance並且指定為他的 prototype(Line 11)。這差異也造成三個地方要注意:
1. 上圖有了 SubType Prototype 的 __proto__到 SuperType Prototype這個連結關係,而原本在 SuperType存在的屬性跟方法也同時存在 SubType.prototype。
2. getSuperValue()這方法仍然在 SuperType.prototype物件當中,那是因為我們宣告他是在 SuperType.prototype當中。而 property則會在 SubType.prototype這個物件當中,是因為他是 instance物件,隨著 new 的物件而存在,我們宣告了 SubType.prototype = new SuperType(),其 SuperType的 this就相當於 SubType.prototype (若要更加延伸探討原因可以參考
[JavaScript] Conditions of this object)。
3. 同時也注意一點就是 instance.constructor指向 SuperType,原因是 SubType.prototype的 constructor屬性也被複寫過去而重新指向到SuperType了。
Prototype Chaining 延展了 prototype搜尋方法跟屬性的機制,若在讀取一個 instance的屬性或方法的時候沒有被找到,會往他的 prototype繼續搜尋。在此案例當我們呼叫 instance.getSuperValue()時候會有三個搜尋的步驟: 1) instance ->2) SubType.prototype->3) SuperType.prototype。
Default Prototypes
在 JavaScript的 Reference Type都繼承自 Object,所以上述範例實際上會是下圖(參考Professional JavaScript for Web Developers Chapter.6 Object-Oriented Programming)。當我們呼叫 instance.toString(),實際上是呼叫 Object.prototype的 toString()方法。
Prototype的觀念一直是 JavaScript蠻值得探討的一個話題,文章若有敘述不清楚地方歡迎大家找我討論,也歡迎大家指教補述。