浏览 1653 次
锁定老帖子 主题:Ext.extend 的一点改进
精华帖 (0) :: 良好帖 (0) :: 新手帖 (7) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-08-09
Extjs 中的模拟继承使用很多,比如 Component 是所有 extjs 组件的基类,机制就是 Ext.extend 函数 ,所有组件实例化前都要调用父类组件的实例化程序,如:
Container :
// private initComponent : function(){ Ext.Container.superclass.initComponent.call(this); ..... }
这个机制也可用于一般的情况,如:
function base(){ } base.prototype.parentMethod=function(str){ alert('父类执行:'+str); } var child=Ext.extend(base,{ parentMethod:function(str){ //很不方便 child.superclass.parentMethod.apply(this,[str]); //这样不是很好么 //this.supermethod(str); } }); var c=new child(); c.parentMethod('原来的ext.extend');
就像注释中所说的,在一个子类方法中要调用父类的方法,extjs的写法有点啰嗦 ,若是override的那么直接supermethod 不就可以了么。
部分借鉴了 base2 中所实现的 javascript 类模拟机制,改造了一下 Ext.extend 很容易就实现了上述简单的写法:
改进的 Ext.extend
(function(){ //函数中是否包含调用父类对应函数的代码(opera 函数不能表示) var hasSuper= /supermethod/.test(function(){supermethod;}) ? /\bsupermethod\b/ : /.*/; Ext.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; //不直接设置 sb.prototype = new F(); //sbp = sb.prototype = new F(); sbp = new F(); // 手动设置 for (var name in overrides) { if(!overrides.hasOwnProperty(name)) return; // 父类有这个函数 sbp[name] = typeof overrides[name] == "function" && typeof sbp[name] == "function" //并且 override的函数调用了父类函数 && hasSuper.test(overrides[name]) ? (function(name, fn){ return function() { var tmp = this.supermethod; //调用时把父类的函数存在自己的context中,供子类函数调用 this.supermethod = spp[name]; var ret = fn.apply(this, arguments); //恢复原状,只保证调用时可以就行了 this.supermethod = tmp; return ret; }; })(name, overrides[name]) : overrides[name]; } sb.prototype=sbp; 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的函数可以很直接的使用:
改进后的使用
child=Ext.extend(base,{ parentMethod:function(str){ this.supermethod(str); alert("call child"); }, //原来用法保留 otherMethod:function(){ child.superclass.parentMethod.apply(this,['test2']); } }); grand=Ext.extend(child,{ parentMethod:function(str){ this.supermethod(str); alert("call grand"); } }); var c=new grand(); c.parentMethod('改进的ext.extend'); c.otherMethod();
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |