一般的,如果我們定義一個類,會定義一個function對象,然後將公用方法寫到其原型上,例如:
var Tiger = function(){}
Tiger.prototype.Hunting = function(){}
但是要建立一個完善的架構或者類庫,沒有繼承幫忙,組織代碼將是一件非常辛苦且難以管理的工作。Js中的類是function對象,實現繼承,主要要將子類的原型設定為父類的一個執行個體(這樣子類就用有了父類原型的所有成員),並重新將子類原型的構造器設定為子類自己。如以下代碼所示:
function Animal(){}
function Tiger(){}
Tiger.prototype = new Animal()
Tiger.prototype.constructor = Tiger
實現繼承並不難,將上面的Animal和Tiger參數化封裝為一個方法就可以實現(當然實際應用中就要複製一些了),代碼如下:
function Extend(subFn, superFn){
subFn.prototype = new superFn()
subFn.prototype.constructor = subFn
}
Ext作為一個優秀的架構,當然也少不了繼承的實現。如前一篇文章所談到的,現在讓我們一行行代碼理解Ext.extend
extend : function(){
// inline overrides
var io = function(o){
for(var m in o){
this[m] = o[m];
}
};
return function(sb, sp, overrides){
if(typeof sp == 'object'){
overrides = sp;
sp = sb;
sb = function(){sp.apply(this, arguments);};
}
var F = function(){}, sbp, spp = sp.prototype;
F.prototype = spp;
sbp = sb.prototype = new F();
sbp.constructor=sb;
sb.superclass=spp;
if(spp.constructor == Object.prototype.constructor){
spp.constructor=sp;
}
sb.override = function(o){
Ext.override(sb, o);
};
sbp.override = io;
Ext.override(sb, overrides);
return sb;
};
}()
本來只有兩行代碼就可以實現的繼承變成了近30行,Ext都做了什麼呢?通常情況下只傳入兩個類型的話(subFn和superFn),上面的代碼將簡化為
extend : function(){
// inline overrides
var io = function(o){
for(var m in o){
this[m] = o[m];
}
};
return function(sb, sp, overrides){
var F = function(){}, sbp, spp = sp.prototype;
F.prototype = spp;
sbp = sb.prototype = new F();
sbp.constructor=sb;
sb.superclass=spp;
sb.override = function(o){
Ext.override(sb, o);
};
sbp.override = io;
Ext.override(sb, overrides);
return sb;
};
}()
定義一個空函數,將其原型設定為sp的原型spp,其實F就是sp的一個替身,理解的時候可以認為就是sp。將子類sb的原型設定為F的一個執行個體,然後再將其原型的構造器設定為自己sb,為了方便找到父類sp,在子類sb上添加了一個superclass屬性為父類sp的原型spp。為了方便擴充屬性,在子類sb上添加了屬性重寫的override方法,也在其原型上添加了override方法(這樣其所有執行個體對象就可以從一個對象重寫現有屬性了)。
到這裡算是對繼承有了一些瞭解(不到位的地方在以後的閱讀中繼續加強)。好了,有了繼承的支援,我們就可以加速類型的擴充了。
繼續 閱讀Ext 學習Javascript(三) Event和Observeable