Extjs2继承函数简单分析及疑问

Java代码
Ext = {version: '2.0'};

Ext = {version: '2.0'};

Java代码
/**
* 继承,并由传递的值决定是否覆盖原对象的属性
* 返回的对象中也增加了override()函数,用于覆盖实例的成员
* @param {Object} subclass 子类,用于继承(该类继承了父类所有属性,并最终返回该对象)
* @param {Object} superclass 父类,被继承
* @param {Object} overrides (该参数可选) 一个对象,将它本身携带的属性对子类进行覆盖
* @method 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;//@1
F.prototype = spp;//原型链继承基本原理的实现只有这三行的部分代码 其他代码都具有技巧性,都是为了达到一定的效果或者避免一些缺点。
sbp = sb.prototype = new F();//用空函数 可以避免子类或得父类的实例变量 即直接定义在构造函数中的变量 避免浪费,也正是这个原因,我们需要的constructor superclass要采用下面的处理。
sbp.constructor=sb;//@2 设置子函数的构造函数 为什么不是sb.constructor=sb呢,请了解javascript 关于constructor的知识,主意是作为类来使用的,constructor属性为类的实例提供方便,参考@1
sb.superclass=spp;//这里是apply sbp的superclass 这样做不仅sb的实例可以得到superclass sb本身也可以得到
if(spp.constructor == Object.prototype.constructor){//
spp.constructor=sp;//父类sp到达继承链的顶级 如{} 等 得指定他们的spp的构造函数 方便所有继承系列中的子类能正确调用到父类的构造函数 避免调用到Object.prototype.constructor
}
sb.override = function(o){//@3
Ext.override(sb, o);
};//给子类本身加上override方法 方便sb的重载、重写实现
sbp.override = io;

//给sb的子类提供好override方法//@4 @3@4可对比@2并思考区别, 为什么不写成sbp.override=function(o){Ext.apply(this,o);} ?<SPAN>


</SPAN>











Ext.override(sb, overrides);//override属性 类级别的 区别前面 只有一个参数的 是实例级别的 没啥好说的吧?
return sb;
};
}(),

/**
* 继承,并由传递的值决定是否覆盖原对象的属性
* 返回的对象中也增加了override()函数,用于覆盖实例的成员
* @param {Object} subclass 子类,用于继承(该类继承了父类所有属性,并最终返回该对象)
* @param {Object} superclass 父类,被继承
* @param {Object} overrides (该参数可选) 一个对象,将它本身携带的属性对子类进行覆盖
* @method 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;//@1
F.prototype = spp;//原型链继承基本原理的实现只有这三行的部分代码 其他代码都具有技巧性,都是为了达到一定的效果或者避免一些缺点。
sbp = sb.prototype = new F();//用空函数 可以避免子类或得父类的实例变量 即直接定义在构造函数中的变量 避免浪费,也正是这个原因,我们需要的constructor superclass要采用下面的处理。
sbp.constructor=sb;//@2 设置子函数的构造函数 为什么不是sb.constructor=sb呢,请了解javascript 关于constructor的知识,主意是作为类来使用的,constructor属性为类的实例提供方便,参考@1
sb.superclass=spp;//这里是apply sbp的superclass 这样做不仅sb的实例可以得到superclass sb本身也可以得到
if(spp.constructor == Object.prototype.constructor){//
spp.constructor=sp;//父类sp到达继承链的顶级 如{} 等 得指定他们的spp的构造函数 方便所有继承系列中的子类能正确调用到父类的构造函数 避免调用到Object.prototype.constructor
}
sb.override = function(o){//@3
Ext.override(sb, o);
};//给子类本身加上override方法 方便sb的重载、重写实现
sbp.override = io;

//给sb的子类提供好override方法//@4 @3@4可对比@2并思考区别, 为什么不写成sbp.override=function(o){Ext.apply(this,o);} ?


Ext.override(sb, overrides);//override属性 类级别的 区别前面 只有一个参数的 是实例级别的 没啥好说的吧?
return sb;
};
}(),

一、关于F的用法
Js中的类是function对象,实现原型链继承,主要要将子类的原型设置为父类的一个实例(这样子类就用有了父类原型的所有成员),并重新将子类原型的构造器设置为子类自己。
如以下代码所示:



Java代码
function Animal(){}
function Tiger(){}
Tiger.prototype = new Animal()//@1
Tiger.prototype.constructor = Tiger//因为@1已经使Tiger.prototype.constructor 变为Animal,需要纠正。

function Animal(){}
function Tiger(){}
Tiger.prototype = new Animal()//@1
Tiger.prototype.constructor = Tiger//因为@1已经使Tiger.prototype.constructor 变为Animal,需要纠正。


问题(一):为什么不采用如下这种方式呢?



Java代码
function Animal(){}
function Tiger(){}
Tiger.prototype =Animal.prototype//因为@1

function Animal(){}
function Tiger(){}
Tiger.prototype =Animal.prototype//因为@1Java代码
Tiger.prototype.constructor = Tiger//因为@1已经使Tiger.prototype.constructor 变为Animal,需要纠正。

Tiger.prototype.constructor = Tiger//因为@1已经使Tiger.prototype.constructor 变为Animal,需要纠正。


原因:为了避免对sb原型对象的操作,联动影响sp的原型对象。
问题(二):那么Ext.extent为什么要使用F这个空函数呢?
原因:用空函数,可以避免子类获得父类的实例变量 即直接定义在构造函数中的变量 避免浪费。
二、sb的原型属性是否保留

当typeof sp == "function"时,sb的原型将被替换,不保留任何原型属性,sb的superclass指向sp的原型对象;
3,当typeof sp == "object"时,sb的原型属性将被保留,sb的superclass指向自己的原型对象,效果略等同于override, 区别在于指定了superclass

三、其他要点
(一)apply,applyIf主要用于typeof == "object"时的对象操作
(二)override,extend主要用于typeof == "function"时的对象原型操作
(三)一般有两种方式使用ext.extend,建议尽量使用第二种,省去了config自己操作的麻烦。Component.js

第一种:

Java代码
<SPAN style="FONT-SIZE: medium"> /* // protected
* Function to be implemented by Component subclasses to be part of standard component initialization flow (it is empty by default).
*/
// Traditional constructor:
Ext.Foo = function(config){
// call superclass constructor:
Ext.Foo.superclass.constructor.call(this, config);

this.addEvents({
// add events
});
};
Ext.extend(Ext.Foo, Ext.Bar, {
// class body
}</SPAN>

/* // protected
* Function to be implemented by Component subclasses to be part of standard component initialization flow (it is empty by default).
*/
// Traditional constructor:
Ext.Foo = function(config){
// call superclass constructor:
Ext.Foo.superclass.constructor.call(this, config);

this.addEvents({
// add events
});
};
Ext.extend(Ext.Foo, Ext.Bar, {
// class body
}


第二种:


Java代码
<SPAN style="FONT-SIZE: medium">// initComponent replaces the constructor:
Ext.Foo = Ext.extend(Ext.Bar, {
initComponent : function(){
// call superclass initComponent
Ext.Container.superclass.initComponent.call(this);

this.addEvents({
// add events
});
}
}
</SPAN>

// initComponent replaces the constructor:
Ext.Foo = Ext.extend(Ext.Bar, {
initComponent : function(){
// call superclass initComponent
Ext.Container.superclass.initComponent.call(this);

this.addEvents({
// add events
});
}
}


四、js基础知识总结:

typeof 运算符
返回一个用来表示表达式的数据类型的字符串。

typeof
[(
)expression
[]
] ;


expression 参数是需要查找类型信息的任意表达式 。



http://book.csdn.net/bookfiles/110/1001103362.shtml

ps:js设计的一个小错误,请主意。



原始类型、引用类型 :http://book.csdn.net/bookfiles/110/1001103364.shtml

这本书可以看看:http://book.csdn.net/bookfiles/110/#c1

说明
typeof 运算符把类型信息当作字符串返回。typeof 返回值有六种可能: "number," "string," "boolean," "object," "function," 和 "undefined."

typeof 语法中的圆括号是可选项。




typeof的结果只有可能是'number','string','boolean','function','object','undefined'。new 生成的对象typeof为object。
instanceof右边一定是Number,String,Boolean,Function,Object,自定义函数对象。
.constructor的结果也只可能是Number,String,Boolean,Function,Object,自定义函数对象。
且Number,String,Boolean,Function,Object,自定义函数对象,她们的.constructor都是Function,typeof 她们 == 'function'。

掌握javascript的prototype链原理及{}.prototype为null//undifined 但是请主意Object.prototype为“object” 因为typeof Object 为"function",由此可见所以可以使用new的关键字或自定义函数, 如

new Number (),new String (),new Boolean (),new Function (),new Function (),他们都是函数类型。



五、使用extjs的一点经验

(一)充分理解继承。

(二)尽量照抄例子,从简单到复杂地进行修改,直到得到你需要的界面效果。

(三)碰到问题,快速使用google codesearch等搜索引擎。

(四)尽可能少的使用ext.get 和ext.getcmp,因为你写的类可能要再某些地方复用,避免id冲突

(后续补充中...)



六、一些疑问

(一)if(spp.constructor == Object.prototype.constructor){// 不是很理解,期待有人点拨一下



答:主要是为了解决sp为object时的继承问题 如 AB = Ext.extend(sb,Object,overrides )





(二)sbp.override = io; 为什么要使用io这个函数,类色的函数不是本来就有了嘛 如Ext.apply



答:的确没有

Js代码
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;
};

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;
}; 有

Js代码
typeof c == 'object'

typeof c == 'object' 这个限制,

applyif 虽然没这个限制,但是该函数的目的是没有的属性才会增加。

Js代码
applyIf : function(o, c){
if(o && c){
for(var p in c){
if(typeof o[p] == "undefined"){ o[p] = c[p]; }
}
}
return o;
},

applyIf : function(o, c){
if(o && c){
for(var p in c){
if(typeof o[p] == "undefined"){ o[p] = c[p]; }
}
}
return o;
},

override 是针对object.prototype的 所以只能这里写一个了。

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

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

(三)a.superclass.constructor是c而访问不到b

sb.superclass=spp;
if(spp.constructor == Object.prototype.constructor){
spp.constructor=sp;
}
换成
sb.superclass=sp;
岂不是更好?

答:而且ext用的是原型链继承 subclass就是通过prototype的技巧性处理来继承superclass的 这本身是一个逐级向上的递归过程
所以指定superclass指定到superclass的prototype比较合理,而且以后调用也方便 只需要subclass.superclass.method.call
如果像你那样指定的话就需要subclass.superclass.prototype.method.call 反而更复杂了 。

subclass.superclass.call(this) 的方式没有subclass.superclass.constructor.call(this)的方式直观

而且构造函数constructor我感觉也是显示调用比较好,风格比较一致,而且少点潜规则也更容易看懂吧,没必要学java的那种方式,
而且如果superclass没有构造函数的话 按照ext的方式会逐级向更上层的父类调用,直到最顶端。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值