Javascript無參數(shù)和有參數(shù)類繼承問題解決方法
說到Javascript的類繼承,就必然離不開原型鏈,但只通過原型鏈實現(xiàn)的繼承有著不少缺陷。
無參數(shù)類繼承的問題
先看一段示例代碼,實現(xiàn)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
這段代碼的主要問題是:
1.需要實例化A作為B的原型,此時就執(zhí)行了A的構(gòu)造函數(shù)。但按照面向?qū)ο蟮囊?guī)則,實例化B之前,B及其父類A的構(gòu)造函數(shù)都不應(yīng)該執(zhí)行。
2.更改了B的prototype,導(dǎo)致b.constructor不是B而是A。
有參類繼承的問題
假設(shè)A和B都有兩個字符串參數(shù)s1和s2,A中計算了兩段字符串的總長度,B直接以s1、s2為參數(shù)調(diào)用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的原型時沒有參數(shù),所以出現(xiàn)了異常:
s1 is undefined
解決方案
s1和s2的作用域只在B內(nèi),要把它們傳到A,就只能在B中操作,借助函數(shù)的apply方法就可以實現(xiàn)之:
function B(s1, s2) {
A.apply(this, arguments);
alert(this.totalLength);
}
接下來的問題就是如何把A的方法添加到B的原型中去。這也不難,只要遍歷A.prototype,把方法復(fù)制到B.prototype即可。要注意的是,對于同名的方法,自然是子類優(yōu)先(重載),因而不能覆蓋:
for (var m in A.prototype) {
if (!B.prototype[m]) { // 父類不能覆蓋子類的方法
B.prototype[m] = A.prototype[m];
}
}
后記
考慮到C#、Java等高級語言都拋棄了多繼承,因此,本文所討論的也只是單繼承的情況。而本文所述的繼承方法,也會寫成jRaiser的一個擴(kuò)展,遲些發(fā)布。
相關(guān)文章
OpenLayers實現(xiàn)點要素圖層的聚合顯示的方法
在很多情況下,點要素圖層中的要素數(shù)量可能會成百上千,如果一個點要素圖層中的點數(shù)量很多,我們就會采取圖層聚合的方式對其進(jìn)行處理,本文就來介紹一下,感興趣的可以了解一下2021-09-09
獲取offsetTop和offsetLeft值的js代碼(兼容)
offsetTop和offsetLeft的值在某些特殊的情況下是會使用到的,為了實現(xiàn)值的準(zhǔn)確獲取,本文采用js代碼實現(xiàn)下,有需求的朋友可以參考下哈2013-04-04
javascript中內(nèi)置對象Math的介紹及用法案例
Math對象是一個內(nèi)置對象,具有數(shù)學(xué)常數(shù)和函數(shù)的屬性和方法,不是一個函數(shù)對象,下面這篇文章主要給大家介紹了關(guān)于javascript中內(nèi)置對象Math的介紹及用法案例的相關(guān)資料,需要的朋友可以參考下2022-03-03
jQuery $.data()方法使用注意細(xì)節(jié)
前段時間同事在群里對jQuery里的.data()方法接下來介紹jQuery $.data()方法使用注意細(xì)節(jié),需要了解的朋友可以參考下2012-12-12

