透析Extjs的Ext.js源码(五)分析继承的实现
关键字: extjs 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