`

转载 Ext.extend用法(ext的继承)

 
阅读更多

转载Ext.extend用法(ext的继承)收藏

<script type="text/javascript"><!-- function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&amp;u='+escape(d.location.href)+'&amp;c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();} // --></script>

概述

Ext.extendExt的继承机制,这个函数的代码相当难懂。要明白这个函数的代码,首先要知道这个函数如何使用。

使用方式

使用示例

假设有个function名为SuperClass,要实现一个子类,名为MyClass。下面的两种方式都可以实现这个功能。


  1. MyClass=Ext.extend(SuperClass,{/**/});
  2. Ext.extend(MyClass,SuperClass,{/**/});

下面来个具体示例:

  1. vara=function(id){
  2. this.id=id;
  3. }
  4. a.prototype={
  5. tostring:function(){
  6. returnthis.id;
  7. }
  8. };
  9. b=function(id){
  10. b.superclass.constructor.call(this,id);
  11. }
  12. Ext.extend(b,a,{
  13. tostring:function(){
  14. returnString.format("b:{0}",this.id);
  15. }
  16. });
  17. //测试一下
  18. varobj1=newa("obj1");
  19. alert(obj1.tostring());
  20. varobj2=newb("obj2");
  21. alert(obj2.tostring());
或者下面的代码,可以得到同样的效果:

  1. vara=function(id){
  2. this.id=id;
  3. }
  4. a.prototype={
  5. tostring:function(){
  6. returnthis.id;
  7. }
  8. };
  9. b=Ext.extend(a,{
  10. tostring:function(){
  11. returnString.format("b:{0}",this.id);
  12. }
  13. });
  14. //测试一下
  15. varobj1=newa("obj1");
  16. alert(obj1.tostring());
  17. varobj2=newb("obj2");
  18. alert(obj2.tostring());

一个错误例子

下面看个示例:

  1. BaseClass=function(){
  2. this.f1=function(){
  3. alert("f1inbase");
  4. }
  5. this.f2=function(){
  6. alert("f2inbase");
  7. }
  8. }
  9. ChildClass=function(){
  10. ChildClass.superclass.constructor.call(this);
  11. }
  12. Ext.extend(ChildClass,BaseClass,{
  13. f1:function(){
  14. alert("f1inchild");
  15. },
  16. f3:function(){
  17. alert("f3inchild");
  18. }
  19. });
  20. varb=newChildClass();
  21. b.f1();
  22. b.f2();
  23. b.f3();

可以去执行一下,可以发现f1的执行结果仍然是"f1 in base"。并没有真正的达到override的效果。


  1. Ext.extendputsthepropertiesspecifiedinthe3rdargumentintothesubclass'sprototype

也就是说:第三个参数里面的函数被放置在了子类的prototype中。

而在ChildClass.superclass.constructor.call(this);这句上,BaseClassf1成了ChildClass的变量,而不是ChildClass.prototype。通过对JavaScript的原型继承的了解,可以知道,实例变量的优先级是高于prototype的,所以上面的这个代码是达不到override的功能的。

修改的方式如下:

  1. BaseClass=function(){
  2. };
  3. BaseClass.prototype={
  4. f1:function(){
  5. alert("f1inbase");
  6. }
  7. };

代码解读

JavaScript中的继承实现

先了解一下最简单的继承是如何实现的:

  1. functionExtend(subFn,superFn){
  2. subFn.prototype=newsuperFn()
  3. subFn.prototype.constructor=subFn
  4. }
  5. functionAnimal(){
  6. this.say1=function(){
  7. alert("Animal");
  8. }
  9. }
  10. functionTiger(){
  11. this.say2=function(){
  12. alert("Tiger");
  13. }
  14. }
  15. Extend(Tiger,Animal);
  16. vartiger=newTiger();
  17. tiger.say1();//"Animal"
  18. tiger.say2();//"Tiger"

以看到最简单的继承只做了两件事情,一是把subFnprototype设置为superFn的一个实例,然后设置subFn.prototype.constructorsubFn

Ext.extend的代码

Ext.extend函数中用到了Ext.override,这个函数把第二个参数中的所有对象复制到第一个对象的prototype中。首先贴上Ext.override函数的代码:

  1. Ext.override=function(origclass,overrides){
  2. if(overrides){
  3. varp=origclass.prototype;
  4. for(varmethodinoverrides){
  5. p[method]=overrides[method];
  6. }
  7. }
  8. }

然后贴上Ext.extend的代码:

  1. /**
  2. *继承,并由传递的值决定是否覆盖原对象的属性
  3. *返回的对象中也增加了override()函数,用于覆盖实例的成员
  4. *@param{Object}subclass子类,用于继承(该类继承了父类所有属性,并最终返回该对象)
  5. *@param{Object}superclass父类,被继承
  6. *@param{Object}overrides(该参数可选)一个对象,将它本身携带的属性对子类进行覆盖
  7. *@methodextend
  8. */
  9. functionextend(){
  10. //inlineoverrides
  11. vario=function(o){
  12. for(varmino){
  13. this[m]=o[m];
  14. }
  15. };
  16. returnfunction(sb,sp,overrides){
  17. if(typeofsp=='object'){
  18. overrides=sp;
  19. sp=sb;
  20. sb=function(){sp.apply(this,arguments);};
  21. }
  22. varF=function(){},sbp,spp=sp.prototype;
  23. F.prototype=spp;
  24. sbp=sb.prototype=newF();
  25. sbp.constructor=sb;
  26. sb.superclass=spp;
  27. if(spp.constructor==Object.prototype.constructor){
  28. spp.constructor=sp;
  29. }
  30. sb.override=function(o){
  31. Ext.override(sb,o);
  32. };
  33. sbp.override=io;
  34. Ext.override(sb,overrides);
  35. returnsb;
  36. };
  37. }();

代码中进行了太多的简写,看起来不是特别方便,把代码中的简写补全,代码如下:

  1. functionextend(){
  2. //inlineoverrides
  3. varinlineOverride=function(o){
  4. for(varmino){
  5. this[m]=o[m];
  6. }
  7. };
  8. returnfunction(subFn,superFn,overrides){
  9. if(typeofsuperFn=='object'){
  10. //如果subFn也是对象的话(一般来说subFn这里放的是父类的构造函数),那么第三个参数overrides参数相当于被忽略掉
  11. overrides=superFn;
  12. superFn=subFn;
  13. //subFn重新定义了函数
  14. subFn=function(){
  15. superFn.apply(this,arguments);
  16. };
  17. }
  18. varF=function(){
  19. },subFnPrototype,superFnPrototype=superFn.prototype;
  20. F.prototype=superFnPrototype;
  21. subFnPrototype=subFn.prototype=newF();
  22. subFnPrototype.constructor=subFn;
  23. subFn.superclass=superFnPrototype;
  24. if(superFnPrototype.constructor==Object.prototype.constructor){
  25. superFnPrototype.constructor=superFn;
  26. }
  27. subFn.override=function(obj){
  28. Ext.override(subFn,obj);
  29. };
  30. subFnPrototype.override=inlineOverride;
  31. Ext.override(subFn,overrides);
  32. returnsubFn;
  33. };
  34. };

补全以后也不是特别容易明白,那么我们就把这个代码分开,分为2个参数和3个参数。

两个参数的Ext.extend代码

首先把代码改写成两个参数的。

  1. //两个参数的时候的代码,注意第二个参数必须为object
  2. functionextend(){
  3. //inlineoverrides
  4. varinlineOverride=function(o){
  5. for(varmino){
  6. this[m]=o[m];
  7. }
  8. };
  9. returnfunction(superFn,overrides){
  10. varsubFn=function(){
  11. superFn.apply(this,arguments);
  12. };
  13. varF=function(){
  14. },subFnPrototype,superFnPrototype=superFn.prototype;
  15. F.prototype=superFnPrototype;
  16. //注意下面两句就是上面最简单的继承实现。
  17. subFnPrototype=subFn.prototype=newF();
  18. subFnPrototype.constructor=subFn;
  19. //添加了superclass属性指向superFn的Prototype
  20. subFn.superclass=superFnPrototype;
  21. //为subFn和subFnPrototype添加override函数
  22. subFn.override=function(obj){
  23. Ext.override(subFn,obj);
  24. };
  25. subFnPrototype.override=inlineOverride;
  26. //覆盖掉子类prototype中的属性
  27. Ext.override(subFn,overrides);
  28. returnsubFn;
  29. };
  30. };

从注释中可以看到,做的工作很简单,只是定义一个subFn函数,这个函数中会调用superFn函数。定义了subFn以后,就使用上面的最简单的继承方式实现继承。然后为subFnsubFnprototype添加了一个override函数。最后的Ext.override(subFn, overrides);overrides中的函数写入subFnprototype中。

三个参数的Ext.extend代码

下面我们把函数改写为只处理3个参数的,改写后的代码如下:

  1. //三个参数时的代码
  2. functionextend(){
  3. //inlineoverrides
  4. varinlineOverride=function(o){
  5. for(varmino){
  6. this[m]=o[m];
  7. }
  8. };
  9. returnfunction(subFn,superFn,overrides){
  10. varF=function(){
  11. },subFnPrototype,superFnPrototype=superFn.prototype;
  12. F.prototype=superFnPrototype;
  13. //注意下面两句就是上面最简单的继承实现。
  14. subFnPrototype=subFn.prototype=newF();
  15. subFnPrototype.constructor=subFn;
  16. //添加了superclass属性指向superFn的Prototype
  17. subFn.superclass=superFnPrototype;
  18. //为subFn和subFnPrototype添加override函数
  19. subFn.override=function(obj){
  20. Ext.override(subFn,obj);
  21. };
  22. subFnPrototype.override=inlineOverride;
  23. //覆盖掉子类prototype中的属性
  24. Ext.override(subFn,overrides);
  25. returnsubFn;
  26. };
  27. };

过程与两个参数的时候相差无几,只是两个参数的时候,subFn时重新定义的一个function,而三个参数的时候,这个步骤就省略了。

总结及说明

这样大家就对这个函数很明白了吧,也可以知道Ext.extend的继承只会覆写构造函数prototype中的对象,使用的时候需要多加注意。

注意下面一段代码

  1. if(superFnPrototype.constructor==Object.prototype.constructor){
  2. superFnPrototype.constructor=superFn;
  3. }

这段代码我在改写的Ext.extend中省略掉了。原因在于我尝试了多次,发现参数为两个参数的时候,只有第一个参数为Object对象或者为3个参数的时候,第二个参数为Object才会进入此段代码。

但是发现superFn也时function Object(){},在IEFF下都是如此。那么我就不是很清楚这段代码到底是什么用的了,若有清楚的,告诉一声,哈。

分享到:
评论

相关推荐

    EXT是一款强大的AJAX框架

    要使用这个CRUD面板,需要继承实现它,我们举一个例子 //继承CrudPanel,创建污水厂管理面板 AddPlantPanel=Ext.extend(Mis.Ext.CrudPanel,{ id:"AddPlantPanel",//id号是表示一个面板的唯一标志 title:"污水厂管理...

    Ext Js权威指南(.zip.001

    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 ...

    Ext+JS高级程序设计.rar

    9.1 利用Ext.extend实现继承 254 9.2 与Ext扩展相关的预备知识 256 9.2.1 定义命名空间 256 9.2.2 重写构造函数 257 9.2.3 继承组件的一些准备 257 9.2.4 常用的辅助函数 258 9.2.5 使用xtype 258 9.3 实现一个功能...

    jQuery中$.extend()用法实例

    本文实例讲述了jQuery中$.extend()用法。分享给大家供大家参考。具体分析如下: $.extend()方法定义如下: jQuery.extend([deep], target, object1, [objectN]) 用一个或多个其他对象来扩展一个对象,返回被扩展的...

    精通JS脚本之ExtJS框架.part1.rar

    14.1 利用Ext.extend实现继承 14.2 与ExtJS扩展相关的预备知识 14.2.1 定义命名空间 14.2.2 使用xtype 14.3 用户扩展和插件 14.3.1 编写自定义用户扩展 14.3.2 常用插件UploadDialog 14.3.3 常用插件...

    精通JS脚本之ExtJS框架.part2.rar

    14.1 利用Ext.extend实现继承 14.2 与ExtJS扩展相关的预备知识 14.2.1 定义命名空间 14.2.2 使用xtype 14.3 用户扩展和插件 14.3.1 编写自定义用户扩展 14.3.2 常用插件UploadDialog 14.3.3 常用插件...

    jQuery继承extend用法详解

    本文实例为大家jQuery继承extend用法,供大家参考,具体内容如下 js代码 //直接基于jQuery的扩展,判断是否为空 $.isBlank = function(obj){ return(typeof(obj)=='undefined'||obj==''||obj==null); } //直接...

    PHP类继承 extends使用介绍

    出来工作这么久了,项目经验倒是不少,但是当问及底层的东西时候,常常是一言不发了。现在项目设计底层的东西越来越少,可以说是真正用到的也就是那么一点,真正核心的东西...被继承的方法和属性可以通过用同样的名字重

    详解vue mixins和extends的巧妙用法

    vue提供了mixins、extends配置项,最近使用中发现很好用。 混合mixins和继承extends 看看官方文档怎么写的,其实两个都可以理解为继承,mixins接收对象数组(可理解为多继承),extends接收的是对象或函数(可理解为...

    Java的extends使用方法

    理解继承是理解面向对象程序设计的关键。在Java中,通过keywordextends继承一个已有的类,被继承的类称为父类(超类,基类),新的类称为子类(派生类)。在Java中不同意多继承。  (1)继承 class Animal{ void eat...

    对于JS继承详细介绍( 原型链,构造函数,组合,原型式,寄生式,寄生组合,Class extends)

    JS中继承可以按照是否使用object函数(在下文中会提到),将继承分成两部分(Object.create是ES5新增的方法,用来规范化这个函数)。 其中,原型链继承和原型式继承有一样的优缺点,构造函数继承与寄生式继承也相互...

Global site tag (gtag.js) - Google Analytics