再論Javascript的類繼承

來源:互聯網
上載者:User

無參數類繼承的問題

先看一段範例程式碼,實現B繼承於A:
複製代碼 代碼如下:
function A() {
}
A.prototype.a1 = function() {
};

function B() {
}
B.prototype = new A();
B.prototype.b1 = function() {
};

var b = new B();
alert(b.constructor == A); // true
alert(b.constructor == B); // false

這段代碼的主要問題是:

* 需要執行個體化A作為B的原型,此時就執行了A的建構函式。但按照物件導向的規則,執行個體化B之前,B及其父類A的建構函式都不應該執行。
* 更改了B的prototype,導致b.constructor不是B而是A。

有參類繼承的問題

假設A和B都有兩個字串參數s1和s2,A中計算了兩段字串的總長度,B直接以s1、s2為參數調用A:
複製代碼 代碼如下:
function A(s1, s2) {
  this.totalLength = s1.length + s2.length;
}
A.prototype.a1 = function() {  
};

function B(s1, s2) {
}
B.prototype = new A();
B.prototype.b1 = function() {
};

new B("ab", "123");

可以看到,這段代碼中根本沒有辦法把s1和s2傳到A,而又因為執行個體化A作為B的原型時沒有參數,所以出現了異常:
複製代碼 代碼如下:
s1 is undefined

解決方案

s1和s2的範圍只在B內,要把它們傳到A,就只能在B中操作,藉助函數的apply方法就可以實現之:
複製代碼 代碼如下:
function B(s1, s2) {
  A.apply(this, arguments);
  alert(this.totalLength);
}

接下來的問題就是如何把A的方法添加到B的原型中去。這也不難,只要遍曆A.prototype,把方法複製到B.prototype即可。要注意的是,對於同名的方法,自然是子類優先(重載),因而不能覆蓋:
複製代碼 代碼如下:
for (var m in A.prototype) {
  if (!B.prototype[m]) { // 父類不能覆蓋子類的方法
    B.prototype[m] = A.prototype[m];
  }
}

後記

考慮到C#、Java等進階語言都拋棄了多繼承,因此,本文所討論的也只是單繼承的情況。而本文所述的繼承方法,也會寫成jRaiser的一個擴充,遲些發布。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.