說到Javascript的類別繼承,就必然離不開原型鏈,但只透過原型鏈實現的繼承有著不少缺陷。
無參數類別繼承的問題
先看一段範例程式碼,實作B繼承於A:
function B() {
}
B.prototype = new A();
B.prototype.b1 = function() { };
var b = new B();
alert(b.constructor == A); // true
alert(b.constructor == B); // false
1.需要實例化A作為B的原型,此時就執行了A的建構子。但依照物件導向的規則,在實例化B之前,B及其父類別A的建構子都不應該執行。
2.更改了B的prototype,導致b.constructor不是B而是A。
有參類繼承的問題
假設A和B都有兩個字串參數s1和s2,A中計算了兩段字串的總長度,B直接以s1、s2為參數呼叫A:
function B(s1, s2) {
}
B.prototype = new A();
B.prototype.b1 = function() {
};
new B("ab", "123");
s1和s2的作用域只在B內,要把它們傳到A,就只能在B中操作,借助函數的apply方法就可以實現之:
考慮到C#、Java等高階語言都拋棄了多繼承,因此,本文所討論的也只是單繼承的情況。而本文所述的繼承方法,也會寫成jRaiser的一個擴展,遲些發布。