【第六胖】(5)EXT.JS文件解析--分析繼承的實現

ext中有關繼承的實現的關鍵代碼如下:(Ext.js中)

 

extend:

extend : function(){
            // inline overrides
            var io = function(o){
                for(var m in o){
                    this[m] = o[m];
                }
            };
            var oc = Object.prototype.constructor;
            
            return function(sb, sp, overrides){
                if(typeof sp == 'object'){
                    overrides = sp;
                    sp = sb;
                    sb = overrides.constructor != oc ? overrides.constructor : 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 == oc){
                    spp.constructor=sp;
                }
                sb.override = function(o){
                    Ext.override(sb, o);
                };
                sbp.override = io;
                Ext.override(sb, overrides);
                sb.extend = function(o){Ext.extend(sb, o);};
                return sb;
            };
        }()

 

override:

override : function(origclass, overrides){
            if(overrides){
                var p = origclass.prototype;
                for(var method in overrides){
                    p[method] = overrides[method];
                }
            }
        }

 

 

Ext.apply:

Ext.apply = function(o, c, defaults){
    if(defaults){
        // no "this" reference for friendly out of scope calls
        Ext.apply(o, defaults);
    }
    if(o && c && typeof c == 'object'){
        for(var p in c){
            o[p] = c[p];
        }
    }
    return o;
};

 
最關鍵的是extend部分的代碼,它使得如果子類沒有constructor(或者說子類的constructor就是個默認的Object),那麼當new一個子類的時候,會調用他的父類的構造器,因此,我們看到Panel是直接通過Ext.Panel = Ext.extend(Ext.Contailer,{...});的方式直接定義的,在new Panel({...})的時候就能層層進去一直到有構造器的超類Ext.Component,並執行這個超類的構造器裏的代碼。而Ext.Component的構造器代碼中有this.initComponet()方法,這樣就能夠調用子類的initComponent()方法,而子類的initComponent()方法中都有子類名.superclass.initComponent();這樣的代碼來調用父類的init方法,這樣我們在new一個子類的後就能夠直接初始化了所有的信息。
extend中最關鍵的一句話是:
sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};
它表示了執行父類構造器的原因,
new對象時,就是執行這個function(){sp.apply(this, arguments);}方法,
sp.applay()執行時,父類構造器就會馬上被執行。

比較並執行下面的代碼就可以理解了上面說的內容了:

 1、子類有構造器的情況

Parent = function() {
	alert("parent");
};
Child = function() {
	alert("child");
};
Ext.extend(Child, Parent, {
	init : function() {
		alert("child's init function");
	}
});
var cl = new Child();// 輸出結果:child
cl.init();// 輸出結果:child's init function

 

2、子類沒有構造器的情況

Parent = function() {
	alert("parent");
};
Child = Ext.extend(Parent, {
	init : function() {
		alert("child's init function");
	}
});
var cl = new Child();// 輸出結果:parent
cl.init();// 輸出結果:child's init function

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章