ExtJS 3.4 类继承机制的实现
ExtJS类继承机制主要靠Ext.extend(sb,sp,overrides)
来实现,主要讲解该方法;该方法可以作为通用的javascript的类继承机制
面向对象的基本特征
在说类继承机制实现之前,首先需要继承的特点是什么?如下:
- 子类继承父类的属性和方法
- 子类可以有自己的构造函数
- 当子类没有构造函数时,将使用父类的构造函数
在说完继承的特点之后,说一下Ext.Extend的两种用法,如下:
- Component继承组件Obsevable
Ext.extend(Ext.Component, Ext.util.Observable,{
//....省略
})
接收3个参数,第一个参数是子类,第二个参数是父类,第三个参数表示重载属性的一个对象,函数最终返回的是子类的一个构造函数
- BoxComponent继承组件Compnent
Ext.BoxComponent = Ext.extend(Ext.Component, {
//....省略
})
接收2个参数,第一个参数是父类,第二个参数表示重载属性的一个对象,函数最终返回的是子类的一个构造函数
具体的解释见源码的注释,源码如下:
extend : function(){//自执行函数,该函数将会自动返回r1处的函数,也就是extend实际上引用r1的这个函数
// inline overrides
var io = function(o){
for(var m in o){
this[m] = o[m];
}
};
var oc = Object.prototype.constructor;
//函数参数的含义,sb:子类构造器,sp:父类构造器,overrides:重载属性的对象
return function(sb, sp, overrides){//...........................................r1
//因为extend函数可以传递3个参数,也可以传递两个参数
//如果sp是对象的话,表示该函数调用的时候传递了两个参数
//此时sp表示重载属性对象,sb表示的是父类
if(typeof sp == 'object'){
overrides = sp;//重载对象
sp = sb;//父类构造器
//判断重载对象中是否设置了constructor属性
//如果设置了,则子类的构造器就是设置的constructor属性
//如果没有设置,则返回父类的构造器,这里实现了继承的第二个和第三个特点
sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};//最终被返回的子类构造器
}
var F = function(){},
sbp,
spp = sp.prototype;//父类构造函数的原型,所有的对象都从创建该对象的构造函数的原型继承属性
F.prototype = spp;//设置F的原型为父类构造函数的原型
//=结合性是从右向左,也就是下面语句等价于 sb.prototype = new F();sbp sb.prototype;
//new F()将会创建一个对象,该对象会从F的原型继承属性,而F的就是父类构造函数的原型,所以new F()创建出的对象将继承父类构造函数的原型中的属性,也就是他的类型是父类
//sb.prototype从sp.prototype中继承属性
sbp = sb.prototype = new F();
sbp.constructor=sb;//设置sbp的构造函数为sb,反向引用
sb.superclass=spp;//设置sb的父类是sp.prototype
//到目前为止,已经设置了sb,设置了sb.prototype,设置了sb.prototye.constructor = sb,设置了sb.superclass = sp.prototype
//这里主要是针对如果传递过来的是两个参数的话,sp实际上是Object
//因为在if(typeof sp == 'object')中sb设置成了sb的值,但是sp的原型中的构造函数仍然指向Object,这里进行调整
if(spp.constructor == oc){
spp.constructor=sp;
}
sb.override = function(o){//定义类方法override
Ext.override(sb, o);
};
sbp.superclass = sbp.supr = (function(){//子类构造函数的的原型的superclass设置为spp,所有由该子类构造函数创建出来的对象都用有superclass属性,指向父类构造函数的原型
return spp;
});
sbp.override = io;//设置子类构造函数原型的override属性,会被所有创建出的对象继承
Ext.override(sb, overrides);
sb.extend = function(o){return Ext.extend(sb, o);};//子类构造函数的extend方法
return sb;
};
}(),