Ext说明

原帖地址:

http://www.meanray.com/pku/jishuziyuan/CHMshouce/chuxuezheyuandi/2010/1117/322.html

 

第一句 Js代码 window.undefined=window.undefined; 兼容IE6以下的浏览器, 有人 解释过了。 定义Ext全局变量 Js代码 Ext={ version: '3.1.0' }; 注意这里没有使用var,不使用var声明变量被认为是不好的编

 第一句

Js代码 
  1. window.undefined = window.undefined;  

 

兼容IE6以下的浏览器,有人 解释过了。

 

定义Ext全局变量

Js代码 
  1. Ext = {  
  2.     version : '3.1.0'  
  3. };  
  

注意这里没有使用var,不使用var声明变量被认为是不好的编程习惯,尤其是函数内声明变量不写var更被称为是无穷无尽的Bug根源。这里则不会,因为变量Ext是该库唯一的全局变量(命名空间)。其它Ext源码中的变量声明都加上了var。

 

给Ext添加静态apply方法,该方法是核心方法之一,会用其扩展Ext。

Js代码 
  1. Ext.apply = function(o, c, defaults){  
  2.     // no "this" reference for friendly out of scope calls  
  3.     if(defaults){  
  4.         Ext.apply(o, defaults);  
  5.     }  
  6.     if(o && c && typeof c == 'object'){  
  7.         for(var p in c){  
  8.             o[p] = c[p];  
  9.         }  
  10.     }  
  11.     return o;  
  12. };  

 

该方法有两种执行方式:

其一,只传o,c时直接将c上的所有属性/方法拷贝给o后返回;

其二,defaults也传时,会将defaults,c上的所有属性/方法都拷贝给o。这里实现的很巧妙,同时有点绕人。

三个参数都传,会执行Ext.apply(o, defaults),即自身实现中调用自身。defaults为c,即当传两个参数时会直接进行对象拷贝。举个例子一目了然,在Ext.apply中加上一个输出语句

Js代码 
  1. Ext.apply = function(o, c, defaults){  
  2.     // no "this" reference for friendly out of scope calls  
  3.     if(defaults){  
  4.         Ext.apply(o, defaults);  
  5.     }  
  6.     if(o && c && typeof c == 'object'){  
  7.         for(var p in c){  
  8.             alert(p); // 此处是添加的输出语句  
  9.             o[p] = c[p];  
  10.         }  
  11.     }  
  12.     return o;  
  13. };  
  14. var obj = {}, obj1 = {name:'jack'}, obj2 = {age:33};  
  15. Ext.apply(obj,obj1,obj2);  

 

会发现先弹出age,再是name。即先拷贝defaults,再是c。

 

接下来是个自执行的匿名函数,执行完后给Ext上扩充许多实用属性或方法。先定义了一些局部变量idSeed,浏览器判断之类。idSeed在做Dom缓存时用到。接下来,

Js代码 
  1. if(isIE6){  
  2.     try{  
  3.         DOC.execCommand("BackgroundImageCache"falsetrue);  
  4.     }catch(e){}  
  5. }  
  

这段代码用来解决IE6下css背景图不缓存bug,也 有人 解释过了。

 

接下就是一个Ext.apply(Ext,{...}),给Ext对象扩展许多实用属性及方法。

 

注意 Ext.isStrict 并非判断html文档模式为严格模式,而是指标准模式,如<!DOCTYPE HTML>声明会返回true。关于文档模式猛击:http://hsivonen.iki.fi/doctype ,国内的 秦歌 翻译了该篇文章。

 

Ext.isSecure 判断采用https或是其它。

 

Ext.applyIf 设计的很巧妙,它会把对象没有的属性和方法拷贝下来,已经有的则不拷贝。Ext.apply 则会覆盖已有的属性/方法。

ECMAScript 5已经发布半年多了,添加了一些新的API方法,如Array的indexOf,forEach等方法,部分新版本浏览器已经支持这些方法来,但我们想为老的浏览器扩展该方法。可能会这样写

Js代码 
  1. var proto = Array.prototype;  
  2. if(!proto.indexOf){  
  3.     proto.indexOf = function(){  
  4.         // ...  
  5.     }  
  6. }  
  7. if(!proto.forEach){  
  8.     proto.forEach = function(){  
  9.         // ...  
  10.     }  
  11. }  
 
即保证优先使用浏览器原生支持的API方法,不支持的使用自定义实现的。但这里每次都需要判断下Array原型上是否存在该方法。
google closure  实现方式类似使用了三元运算符,每次都要判断下,相对丑陋。网上有一些对google closure的  批评 ,
,及一些效率低下的  具体分析  ,批评者甚至包括大牛: Dmitry Baranovskiy 。相对来说,Ext.applyif则使的API的扩展很优雅。
 

Ext.id方法会为HTMLElement元素随机生成一个id,默认以"ext-gen"开头。

 

接下来是Ext.extend方法,该方法也是核心方法之一,整个ext框架继承都是以该方法来扩展的。该方法实现依赖于Ext.override,先看override

Js代码 
  1. override : function(origclass, overrides){  
  2.     if(overrides){  
  3.         var p = origclass.prototype;  
  4.         Ext.apply(p, overrides);  
  5.         if(Ext.isIE && overrides.hasOwnProperty('toString')){  
  6.             p.toString = overrides.toString;  
  7.         }  
  8.     }  
  9. }  

 

将对象overrides的所有属性/方法拷贝到类origclass的原型上。需要注意的是后面的if判断,IE中for in不能遍历对象的Object的toSting等方法,因此需要特别处理一下。我测试IE9 beta重写对象的内置方法如toString后是可用for in遍历的,见 for in的缺陷  。IE9 beta刚刚发布,不知今后Ext团队是否会修改此处的判断。

 

Ext.extend是js继承最经典的实现方式了,我曾经模仿其(简化版)应用在 51ditu 。

Js代码 
  1. extend : function(){  
  2.     // inline overrides  
  3.     var io = function(o){  
  4.         for(var m in o){  
  5.             this[m] = o[m];  
  6.         }  
  7.     };  
  8.     var oc = Object.prototype.constructor;  
  9.     return function(sb, sp, overrides){  
  10.         if(Ext.isObject(sp)){  
  11.             overrides = sp;  
  12.             sp = sb;  
  13.             sb = overrides.constructor != oc ? overrides.constructor : function(){sp.apply(this, arguments);};  
  14.         }  
  15.         var F = function(){},  
  16.             sbp,  
  17.             spp = sp.prototype;  
  18.   
  19.         F.prototype = spp;  
  20.         sbp = sb.prototype = new F();  
  21.         sbp.constructor=sb;  
  22.         sb.superclass=spp;  
  23.         if(spp.constructor == oc){  
  24.             spp.constructor=sp;  
  25.         }  
  26.         sb.override = function(o){  
  27.             Ext.override(sb, o);  
  28.         };  
  29.         sbp.superclass = sbp.supr = (function(){  
  30.             return spp;  
  31.         });  
  32.         sbp.override = io;  
  33.         Ext.override(sb, overrides);  
  34.         sb.extend = function(o){return Ext.extend(sb, o);};  
  35.         return sb;  
  36.     };  
  37. }(),  

 

整体浏览,可以看到 Ext.extend 的实现是通过一个匿名函数执行,执行后返回function,这个function才是真正的Ext.extend。

匿名函数中有两个私有函数io,oc。这种组织代码的方式非常简练,通过匿名函数自执行,在匿名函数中你可以做任何复杂的操作,最终的目的返回需要的接口函数或类。

 

有三个参数,sb、sp、overrides分别代表subClass(子类)、superClass(父类)及覆盖子类的配置参数。

 

以下分三种情况讨论,第一,二种情况Ext.extend的第二个参数都是对象类型

 

1, Ext.extend不光是用来实现类继承的,还可以用来写类,一年前 讨论 过 。 

 

2, 用来扩展Ext库自身类,这种情况是比较频繁的

Js代码 
  1. MyGridPanel = Ext.extend(Ext.grid.GridPanel, {  
  2.     constructor: function(config) {  
  3.         MyGridPanel.superclass.constructor.apply(this, arguments);  
  4.     },  
  5.     yourMethod: function() {  
  6.         // etc.  
  7.     }  
  8. });  

 

这里以Ext.grid.GridPanel为基础,生成了一个新类MyGridPanel

 

3, 真正意义类继承,即第一,二个参数都是类(function)。1年前也总结过js如何实现 继承 及 工具函数 。

 

篇幅已经很长了,重点说下 Ext.apply, Ext.applyif, Ext.override, Ext.extend 的区别 :

 

Ext.apply, Ext.applyif, Ext.override 都是对对象 进行扩展的方法,Ext.extend则是对 操作的方法。

 

Ext.apply 扩展时对已经存在的属性/方法会被覆盖掉, 通常用它来扩展普通对象.

Ext.applyif 扩展时不会覆盖已经存在的属性/方法,通常用它来扩展核心js,如Array.prototype,String.prototype等。

Ext.override 扩展某一个类的原型,可以覆盖toString方法。

 

Ext.extend 用来写类或继承,或者说用来扩展类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值