从Java的角度理解Ext的extend

发表于:2011-12-29 09:33

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Adley    来源:51Testing软件测试网采编

  现在我们来看看Ext.extend,应该完全没有问题了。我们用了两个方法extend,extend2,Ext把它合并为了一个方法Ext.extend,所以它会判断传进来的参数然后进行变换,这样Ext.extend就支持两个参数和三个参数进行调用。对于前面用到拷贝属性,Ext做了一个工具函数叫做Ext.apply,对于将一个对象的属性拷贝到一个类的原型上,Ext做了一个工具类叫做Ext.override。

  1. Ext.extend = function() {  
  2.     // inline overrides 把传入的对象属性复制到到this中  
  3.     var io = function(o) {  
  4.         for (var m in o) {  
  5.             this[m] = o[m];  
  6.         }  
  7.     };  
  8.     //oc其实就是Object函数  
  9.     var oc = Object.prototype.constructor;  
  10.  
  11.     return function(sb, sp, overrides) {  
  12.         //如果第二个参数是个对象而不是类,那么是用两个参数调用的,第一个参数是父类,第二个参数是对象  
  13.         if (typeof sp == 'object') {  
  14.             overrides = sp;  //将第三个参数换为对象  
  15.             sp = sb; //把第一个参数赋值第二个当成父类  
  16.             sb = overrides.constructor != oc ? overrides.constructor : function() {  
  17.                 sp.apply(this, arguments);  
  18.             }; //子类这个构造函数要么是外界传入的名字为constructor,要么就是直接调用超类构造函数的一个函数  
  19.             //传入的constructor除了构造自己还要调用超类的构造函数  
  20.         }  
  21.  
  22.         /**  
  23.          * 继承的两种参数  
  24.          * 1,自己写一个构造函数,初始化一些字段,然后调用超类构造函数,再写一个json对象,里面是要覆盖超类的方法或者追加的方法  
  25.          *   然后这样调用extend(sub,sup,{over1:f,over2:f,addf:f}),就像java的语法  
  26.          *   SubClass extend SuperClass {  
  27.          *      SubClass(){  
  28.          *        super();  
  29.          *      }  
  30.          *   }  
  31.          *  
  32.          *   2,第一种可以理解为模拟java,但是因为构造函数也是数据,所以完全可以把构造函数也放进那个jdon对象,只不过约定好一个名字  
  33.          *   比如constructor,然后这样调用  
  34.          *   extend(sup,{constructor:f,over1:f,over2:f,addf:f})  
  35.          */ 
  36.         var F = function() {  
  37.         },  
  38.                 sbp,  
  39.                 spp = sp.prototype;  
  40.  
  41.         F.prototype = spp;  
  42.         sbp = sb.prototype = new F();  
  43.         //以上用干净函数嫁接得到子类原型  
  44.  
  45.         sbp.constructor = sb; //然后指定一个constructor指回子类,这样就大工告成  
  46.  
  47.         sb.superclass = spp; //在子类上指定一个静态字段指向超类原型,这样在子类构造函数中可访问超类构造函数sub.superclass.constructor.call(this, config)  
  48.  
  49.         /**  
  50.          * 这段代码是防御性的,在自己实现继承的时候,可能会出现原型上的构造函数指向问题,所以如果发现某个超类  
  51.          * 的构造函数是object,要么这个超类却是Object,要么出现了失误,所以这里再一次重设置一下,以防万一,这个代码我们在分析Ext的Observable的时候会提到的它的作用  
  52.          */ 
  53.         if (spp.constructor == oc) {  
  54.             spp.constructor = sp;  
  55.         }  
  56.  
  57.         //子类上方一个静态的重写方法,注意js没有重载,可以用来重写子类原型上的函数  
  58.         sb.override = function(o) {  
  59.             Ext.override(sb, o);  
  60.         };  
  61.  
  62.         //用一个闭包在子类原型上引用一个超类原型,引用的是一个函数  
  63.         sbp.superclass = sbp.supr = (function() {  
  64.             return spp;  
  65.         });  
  66.  
  67.         //子类原型上放置一个重写函数,可以用来覆盖具体实例对象  
  68.         sbp.override = io;  
  69.  
  70.         //在子类原型上重写或添加函数  
  71.         Ext.override(sb, overrides);  
  72.  
  73.         //子类上直接放一个静态继承方法,貌似实现多继承  
  74.         sb.extend = function(o) {  
  75.             return Ext.extend(sb, o);  
  76.         };  
  77.  
  78.         return sb;  
  79.     };  
  80. }();

  现在使用Ext的extend来实现我们之前的继承代码就如下

  1. var Plane = function(o) {  
  2.         this.x = o.x;  
  3.         this.y = o.y;  
  4.     };  
  5.  
  6.  
  7.     Plane.prototype.XY = function() {  
  8.         alert(this.x * this.y);  
  9.     };  
  10.  
  11.     var Space = Ext.extend(Plane, {  
  12.                 constructor : function(o) {  
  13.                     Space.superclass.constructor.call(this, o);  
  14.                     this.z = o.z;  
  15.                 },  
  16.                 XYZ : function() {  
  17.                     alert(this.x * this.y * this.z);  
  18.                 }  
  19.             });  
  20.  
  21.     var space = new Space({ x:2,y:3,z:4});  
  22.  
  23.     space.XY();  
  24.     space.XYZ();

54/5<12345>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号