精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-05-21
Ext = {version: '2.0'};
/**
* 继承,并由传递的值决定是否覆盖原对象的属性
* 返回的对象中也增加了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;
};
}(),
function Animal(){} function Tiger(){} Tiger.prototype = new Animal()//@1 Tiger.prototype.constructor = Tiger//因为@1已经使Tiger.prototype.constructor 变为Animal,需要纠正。
function Animal(){} function Tiger(){} Tiger.prototype =Animal.prototype//因为@1 Tiger.prototype.constructor = Tiger//因为@1已经使Tiger.prototype.constructor 变为Animal,需要纠正。
当typeof sp == "function"时,sb的原型将被替换,不保留任何原型属性,sb的superclass指向sp的原型对象; 第一种: /* // 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
}
第二种: // 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 运算符返回一个用来表示表达式的数据类型的字符串。
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 语法中的圆括号是可选项。
掌握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
答:的确没有 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; }; 有 typeof c == 'object' 这个限制, applyif 虽然没这个限制,但是该函数的目的是没有的属性才会增加。 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的 所以只能这里写一个了。 override : function(origclass, overrides){ if(overrides){ var p = origclass.prototype; for(var method in overrides){ p[method] = overrides[method]; } } },
(三)a.superclass.constructor是c而访问不到b 答:而且ext用的是原型链继承 subclass就是通过prototype的技巧性处理来继承superclass的 这本身是一个逐级向上的递归过程 subclass.superclass.call(this) 的方式没有subclass.superclass.constructor.call(this)的方式直观 而且构造函数constructor我感觉也是显示调用比较好,风格比较一致,而且少点潜规则也更容易看懂吧,没必要学java的那种方式,
八、相关链接 http://zhuaxia.com/pre_channel/4873283 http://bbs.51js.com/viewthread.php?tid=72688&page=1&extra=#pid556697 http://www.kevlindev.com/tutorials/javascript/inheritance/index.htm http://hi.baidu.com/pmzcn/blog/item/92a05fafbe8187f8faed5057.html
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2008-06-10
我刚发的,有研究的朋友请指点指点
|
|
返回顶楼 | |
发表时间:2008-06-11
spp.constructor == Object.prototype.constructor 这个我也不明白,似乎是为解决继承链不能超过两次? 见: 引用 I've found that its easy to build a JS OOP idiom to support one level of inheritance that fails with two more more levels of inheritiance.
http://kevlindev.com/tutorials/javascript/inheritance/index.htm 和 http://sp42.iteye.com/admin/blogs/201143 望引证。 |
|
返回顶楼 | |
发表时间:2008-06-11
sp42 写道 spp.constructor == Object.prototype.constructor 这个我也不明白,似乎是为解决继承链不能超过两次? 见: 引用 I've found that its easy to build a JS OOP idiom to support one level of inheritance that fails with two more more levels of inheritiance.
http://kevlindev.com/tutorials/javascript/inheritance/index.htm 和 http://sp42.iteye.com/admin/blogs/201143 望引证。 我去看了 不是这个原因 不能超过两次 是通过指定subclass的superclass 和 construtor来实现的 |
|
返回顶楼 | |
发表时间:2008-06-11
引用 问题(一):为什么不采用如下这种方式呢? 这个的解释不对吧 真正目的是 为了获得在“构造函数里”通过 this.XXX 方式定义的属性吧 |
|
返回顶楼 | |
发表时间:2008-06-11
fins 写道 引用 问题(一):为什么不采用如下这种方式呢? 这个的解释不对吧 真正目的是 为了获得在“构造函数里”通过 this.XXX 方式定义的属性吧 用new F() 也是得不到的 ,所以需要显式调用 superclass.constructor.call , 空函数就是为了避免得到superclass 构造函数 中定义 的 this.xxx 这种属性啊 ,如果需要则superclass.constructor.call要使用到了. 这个问题的提出也是围绕ext.extend的解决方案的。 |
|
返回顶楼 | |
发表时间:2008-06-11
我说的是第一个问题 不是第二个空函数F的问题
|
|
返回顶楼 | |
发表时间:2008-06-11
空函数是经典的闭包应用,用来解决继承的问题了 呵呵,
至于 "spp.constructor == Object.prototype.constructor", 突然想起ext的OO最近支持constructor关键字的重写了: DeepCMS.client.layout.Menu = obj.extend(UI.TabPanel, { //@override constructor : function(){ var config = { tabPosition : 'bottom' ,title : 'DeepCMS' ,region : 'west' ,deferredRender : false ,border : false ,collapsible : true ,activeTab : 1 ,width : 155 ,items: [ new OA.client.defaultPage.sessionProfile({title: '个人信息'}) ,new OA.client.bigButtonArea() ] }; DeepCMS.client.layout.Menu.superclass.constructor.call(this, config); } }); 注: obj = UI = Ext; 不知会不会跟这个有关系呢?呵呵 |
|
返回顶楼 | |
发表时间:2008-06-16
我搞错了,可以支持inline constructor的原因是:
sb = [b]overrides.constructor != oc ? overrides.constructor[/b] : function(){sp.apply(this, arguments);};//第十四行 |
|
返回顶楼 | |
发表时间:2008-06-17
fins 写道 我说的是第一个问题 不是第二个空函数F的问题
我说了啊, 这些问题的提出都是围绕“ ext的继承为什么要这么写” 构造函数的this.xx在ext的继承方案中就是要避免的。 我不可能说第一个问题是为了“得到”, 第二个问题用空函数是为了“避免得到” 这样来分析吧。 所以第一个问题的着眼点是这种方式带来的副作用是“prototype联动问题”, 而采用new animal() 是可以得到this.xxx,但是这在ext的解决方案里本身是要解决的问题,而不是要达到的效果。 之所以这样分析是用了孤立的方法来各个击破各个可疑之点,从而达到能够全面分析理解各种组合情况的效果 没疑问了吧? |
|
返回顶楼 | |
浏览 8697 次