- 浏览: 54360 次
- 性别:
- 来自: 湖北
最新评论
概述
Ext.extend是Ext的继承机制,这个函数的代码相当难懂。要明白这个函数的代码,首先要知道这个函数如何使用。
使用方式
使用示例
假设有个function名为SuperClass,要实现一个子类,名为MyClass。下面的两种方式都可以实现这个功能。
下面来个具体示例:
或者下面的代码,可以得到同样的效果:
一个错误例子
下面看个示例:
可以去执行一下,可以发现f1的执行结果仍然是"f1 in base"。并没有真正的达到override的效果。
Ext.extend puts the properties specified in the 3rd argument into the subclass's prototype
也就是说:第三个参数里面的函数被放置在了子类的prototype中。
而在ChildClass.superclass.constructor.call(this);这句上,BaseClass的f1成了ChildClass的变量,而不是ChildClass.prototype。通过对JavaScript的原型继承的了解,可以知道,实例变量的优先级是高于prototype的,所以上面的这个代码是达不到override的功能的。
修改的方式如下:
代码解读
JavaScript中的继承实现
先了解一下最简单的继承是如何实现的:
可以看到最简单的继承只做了两件事情,一是把subFn的prototype设置为superFn的一个实例,然后设置subFn.prototype.constructor为subFn。
Ext.extend的代码
Ext.extend函数中用到了Ext.override,这个函数把第二个参数中的所有对象复制到第一个对象的prototype中。首先贴上Ext.override函数的代码:
然后贴上Ext.extend的代码:
代码中进行了太多的简写,看起来不是特别方便,把代码中的简写补全,代码如下:
补全以后也不是特别容易明白,那么我们就把这个代码分开,分为2个参数和3个参数。
两个参数的Ext.extend代码
首先把代码改写成两个参数的。
从注释中可以看到,做的工作很简单,只是定义一个subFn函数,这个函数中会调用superFn函数。定义了subFn以后,就使用上面的最简单的继承方式实现继承。然后为subFn和subFn的prototype添加了一个override函数。最后的Ext.override(subFn, overrides);把overrides中的函数写入subFn的prototype中。
三个参数的Ext.extend代码
下面我们把函数改写为只处理3个参数的,改写后的代码如下:
过程与两个参数的时候相差无几,只是两个参数的时候,subFn时重新定义的一个function,而三个参数的时候,这个步骤就省略了。
总结及说明
这样大家就对这个函数很明白了吧,也可以知道Ext.extend的继承只会覆写构造函数prototype中的对象,使用的时候需要多加注意。
注意下面一段代码:
这段代码我在改写的Ext.extend中省略掉了。原因在于我尝试了多次,发现参数为两个参数的时候,只有第一个参数为Object对象或者为3个参数的时候,第二个参数为Object才会进入此段代码。
Ext.extend是Ext的继承机制,这个函数的代码相当难懂。要明白这个函数的代码,首先要知道这个函数如何使用。
使用方式
使用示例
假设有个function名为SuperClass,要实现一个子类,名为MyClass。下面的两种方式都可以实现这个功能。
MyClass = Ext.extend(SuperClass, { /* */ }); Ext.extend(MyClass, SuperClass, { /* */});
下面来个具体示例:
var a = function(id){ this.id = id; } a.prototype = { tostring : function(){ return this.id; } }; b = function(id){ b.superclass.constructor.call(this, id); } Ext.extend(b, a, { tostring : function(){ return String.format("b:{0}", this.id); } }); //测试一下 var obj1 = new a("obj1"); alert(obj1.tostring()); var obj2 = new b("obj2"); alert(obj2.tostring());
或者下面的代码,可以得到同样的效果:
var a = function(id){ this.id = id; } a.prototype = { tostring : function(){ return this.id; } }; b = Ext.extend(a, { tostring : function(){ return String.format("b:{0}", this.id); } }); //测试一下 var obj1 = new a("obj1"); alert(obj1.tostring()); var obj2 = new b("obj2"); alert(obj2.tostring());
一个错误例子
下面看个示例:
BaseClass = function() { this.f1 = function() { alert("f1 in base"); } this.f2 = function() { alert("f2 in base"); } } ChildClass = function() { ChildClass.superclass.constructor.call(this); } Ext.extend(ChildClass, BaseClass, { f1: function() { alert("f1 in child"); }, f3: function() { alert("f3 in child"); } }); var b = new ChildClass(); b.f1(); b.f2(); b.f3();
可以去执行一下,可以发现f1的执行结果仍然是"f1 in base"。并没有真正的达到override的效果。
Ext.extend puts the properties specified in the 3rd argument into the subclass's prototype
也就是说:第三个参数里面的函数被放置在了子类的prototype中。
而在ChildClass.superclass.constructor.call(this);这句上,BaseClass的f1成了ChildClass的变量,而不是ChildClass.prototype。通过对JavaScript的原型继承的了解,可以知道,实例变量的优先级是高于prototype的,所以上面的这个代码是达不到override的功能的。
修改的方式如下:
BaseClass = function() { }; BaseClass.prototype = { f1: function() { alert("f1 in base"); } };
代码解读
JavaScript中的继承实现
先了解一下最简单的继承是如何实现的:
function Extend(subFn, superFn){ subFn.prototype = new superFn() subFn.prototype.constructor = subFn } function Animal(){ this.say1 = function(){ alert("Animal"); } } function Tiger(){ this.say2 = function(){ alert("Tiger"); } } Extend(Tiger,Animal); var tiger = new Tiger(); tiger.say1();//"Animal" tiger.say2();//"Tiger"
可以看到最简单的继承只做了两件事情,一是把subFn的prototype设置为superFn的一个实例,然后设置subFn.prototype.constructor为subFn。
Ext.extend的代码
Ext.extend函数中用到了Ext.override,这个函数把第二个参数中的所有对象复制到第一个对象的prototype中。首先贴上Ext.override函数的代码:
Ext.override = function(origclass, overrides){ if(overrides){ var p = origclass.prototype; for(var method in overrides){ p[method] = overrides[method]; } } }
然后贴上Ext.extend的代码:
/** * 继承,并由传递的值决定是否覆盖原对象的属性 * 返回的对象中也增加了override()函数,用于覆盖实例的成员 * @param {Object} subclass 子类,用于继承(该类继承了父类所有属性,并最终返回该对象) * @param {Object} superclass 父类,被继承 * @param {Object} overrides (该参数可选) 一个对象,将它本身携带的属性对子类进行覆盖 * @method extend */ function extend (){ // 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; F.prototype = spp; sbp = sb.prototype = new F(); sbp.constructor=sb; sb.superclass=spp; if(spp.constructor == Object.prototype.constructor){ spp.constructor=sp; } sb.override = function(o){ Ext.override(sb, o); }; sbp.override = io; Ext.override(sb, overrides); return sb; }; }();
代码中进行了太多的简写,看起来不是特别方便,把代码中的简写补全,代码如下:
function extend(){ // inline overrides var inlineOverride = function(o){ for (var m in o) { this[m] = o[m]; } }; return function(subFn, superFn, overrides){ if (typeof superFn == 'object') { //如果subFn也是对象的话(一般来说subFn这里放的是父类的构造函数),那么第三个参数overrides参数相当于被忽略掉 overrides = superFn; superFn = subFn; //subFn重新定义了函数 subFn = function(){ superFn.apply(this, arguments); }; } var F = function(){ }, subFnPrototype, superFnPrototype = superFn.prototype; F.prototype = superFnPrototype; subFnPrototype = subFn.prototype = new F(); subFnPrototype.constructor = subFn; subFn.superclass = superFnPrototype; if (superFnPrototype.constructor == Object.prototype.constructor) { superFnPrototype.constructor = superFn; } subFn.override = function(obj){ Ext.override(subFn, obj); }; subFnPrototype.override = inlineOverride; Ext.override(subFn, overrides); return subFn; }; };
补全以后也不是特别容易明白,那么我们就把这个代码分开,分为2个参数和3个参数。
两个参数的Ext.extend代码
首先把代码改写成两个参数的。
//两个参数的时候的代码,注意第二个参数必须为object function extend(){ // inline overrides var inlineOverride = function(o){ for (var m in o) { this[m] = o[m]; } }; return function(superFn, overrides){ var subFn = function(){ superFn.apply(this, arguments); }; var F = function(){ }, subFnPrototype, superFnPrototype = superFn.prototype; F.prototype = superFnPrototype; //注意下面两句就是上面最简单的继承实现。 subFnPrototype = subFn.prototype = new F(); subFnPrototype.constructor = subFn; //添加了superclass属性指向superFn的Prototype subFn.superclass = superFnPrototype; //为subFn和subFnPrototype添加override函数 subFn.override = function(obj){ Ext.override(subFn, obj); }; subFnPrototype.override = inlineOverride; //覆盖掉子类prototype中的属性 Ext.override(subFn, overrides); return subFn; }; };
从注释中可以看到,做的工作很简单,只是定义一个subFn函数,这个函数中会调用superFn函数。定义了subFn以后,就使用上面的最简单的继承方式实现继承。然后为subFn和subFn的prototype添加了一个override函数。最后的Ext.override(subFn, overrides);把overrides中的函数写入subFn的prototype中。
三个参数的Ext.extend代码
下面我们把函数改写为只处理3个参数的,改写后的代码如下:
//三个参数时的代码 function extend(){ // inline overrides var inlineOverride = function(o){ for (var m in o) { this[m] = o[m]; } }; return function(subFn, superFn, overrides){ var F = function(){ }, subFnPrototype, superFnPrototype = superFn.prototype; F.prototype = superFnPrototype; //注意下面两句就是上面最简单的继承实现。 subFnPrototype = subFn.prototype = new F(); subFnPrototype.constructor = subFn; //添加了superclass属性指向superFn的Prototype subFn.superclass = superFnPrototype; //为subFn和subFnPrototype添加override函数 subFn.override = function(obj){ Ext.override(subFn, obj); }; subFnPrototype.override = inlineOverride; //覆盖掉子类prototype中的属性 Ext.override(subFn, overrides); return subFn; }; };
过程与两个参数的时候相差无几,只是两个参数的时候,subFn时重新定义的一个function,而三个参数的时候,这个步骤就省略了。
总结及说明
这样大家就对这个函数很明白了吧,也可以知道Ext.extend的继承只会覆写构造函数prototype中的对象,使用的时候需要多加注意。
注意下面一段代码:
if (superFnPrototype.constructor == Object.prototype.constructor) { superFnPrototype.constructor = superFn; }
这段代码我在改写的Ext.extend中省略掉了。原因在于我尝试了多次,发现参数为两个参数的时候,只有第一个参数为Object对象或者为3个参数的时候,第二个参数为Object才会进入此段代码。
发表评论
-
ExtJS编程思想和开发方式|ExtJS单页面系统|ExtJS单页面应用
2011-04-20 11:53 3843唠叨几句:不要认为 EXTJS 就是一个界面改良,在项目中,我 ... -
Ext.namespace解析
2011-04-20 11:36 994对于这个函数,我一直不太清楚,今天查了查官方的解释,豁然开朗。 ... -
Extjs的代码规范
2011-04-20 11:28 3658一个组件一个JS文件,多个组件拼接成一个模块,这些组件都放在一 ... -
Extjs 继承的使用
2011-04-19 17:05 1676Javascript原始的继承写法: // Traditio ... -
Ext js call方法
2011-04-19 15:58 913转自:http://blog.csdn.net/zhaoqil ... -
[转贴]三种Ext提交数据的方法
2011-04-13 16:28 9531, EXT的form表单ajax提交(默认提交方式) f ... -
ext继承的两种写法
2011-04-13 15:23 1857转自:http://liuna718-163-com.itey ... -
extjs表单FormPanel提交数据和加载数据
2011-04-13 15:21 3680转自:http://liuna718-163-com.itey ... -
看ExtJs API文档的阅读方法(附ExtJS 3.3中文API下载)
2011-04-12 14:58 3478对EXT,下载一个ext2.0的API文件,叫你如何看懂API ...
相关推荐
ext 的详细解读,以及实际应用,与大家一起分享。
jquery.validate.extend.js
原生js实现jquery $.extend方法 通过遍历对象属性来实现
NULL 博文链接:https://bijian1013.iteye.com/blog/2281404
Most configuration options are inherited from Ext.Window (see ExtJs docs). The added ones are: url - the url where to post uploaded files. base_params - additional post params (default to {}). ...
要使用这个CRUD面板,需要继承实现它,我们举一个例子 //继承CrudPanel,创建污水厂管理面板 AddPlantPanel=Ext.extend(Mis.Ext.CrudPanel,{ id:"AddPlantPanel",//id号是表示一个面板的唯一标志 title:"污水厂管理...
关于这个原因有很多种,我只说下我遇到的 我这样 写Store来复用的 代码如下: DocStore = Ext.extend(Ext.data.Store,{ initComponent:function(){ this.proxy = new Ext.data.HttpProxy({url:this.url}); this....
jquery $.fn.extend 引用事件
Jquery实现$.fn.extend和$.extend函数_.docx
前面我们扩展了bind方法和ready函数,这次我要讲一下$.fn.extend 和$.extend函数。 其他的不多说,直接切入主题吧! 先来看看这两个函数的区别: $.fn.extend是为查询的节点对象扩展方法,是基于$的原型扩展的方法...
jQuery添加一个为 add的“静态方法”,之后便可以在引入 jQuery 的地方,使用这个方法了. 2.jQuery.fn.extend(object); 对jQuery.prototype进得扩展,就是为jQuery类添加“成员函数”。jQuery类的实例可以使
主要介绍了jQuery.extend 与 jQuery.fn.extend的用法及区别,结合实例形式分析了jQuery.extend与jQuery.fn.extend的功能、使用方法及区别,需要的朋友可以参考下
6.1.8 ext.domquery的使用方法 / 249 6.1.9 ext js选择器的总结 / 252 6.2 获取单一元素:ext.dom.element / 252 6.2.1 从错误开始 / 252 6.2.2 使用ext.get获取元素 / 253 6.2.3 使用ext.fly获取元素 / 256 ...
下面小编就为大家带来一篇深入理解jquery的$.extend()、$.fn和$.fn.extend()。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
前言 最近一个朋友问我vue.extend和vue.component两者之间有什么区别?突然这么一问竟答不出来,回来想想有必要总结下,所以...// 然后就可以这样来使用 var vm = new myVue({ // 其他选项 }) Vue.component 是用来
jQuery为开发插件提拱了两个方法,分别是: 代码如下: jQuery.fn.extend(object); jQuery.extend(object); jQuery.extend(object); 为扩展jQuery类本身.为类添加新的方法。 jQuery.fn.extend(object);给jQuery对象...
主要介绍了在Python中操作列表之list.extend()方法的使用,是Python入门学习中的基础知识,需要的朋友可以参考下
jQuery.extend 函数详解 Jquery的扩展方法extend是我们在写插件的过程中常用的方法,该方法有一些重载原型,在此,我们一起去了解了解。
jQuery自定义了jQuery.extend()和jQuery.fn.extend()方法.其中jQuery.extend()方法能够创建全局函数或者选择器,而jQuery.fn.extend()方法能够创建jQuery对象方法. 例如: 代码如下: jQuery.extend({ showName : ...