《Ext详解与实践 v3》阅读补充资料:分配命名空间

现代Web 前端的特征之一是由不止一个库所组成的,或者没有达到称为“库”的标准,有可能就是仅仅若干个小部件(Widget) 、某一段的JavaScript 代码(Snippets) 所组成。从开发者的角度而言,你所产生的代码有很大的机会与其他的代码产生冲突,因为我们清楚JavaScript 是一门格外*的语言,允许全局变量星罗棋布地存在,这样的话太多就极容易造成污染。所以有必要采用一定措施降低这种冲突发生的可能性。

《Ext详解与实践 v3》阅读补充资料:分配命名空间

混合的脚本文件

extjs.com 的官方论坛它当前采用了来自三方面的程序(如 ):

  • Ext 精减版(ext.js)
  • Google 流量分析(urchin.js)
  • 论坛自带的vRulletin 脚本(vbulletin_*.js)

如果有新需求,还可能加入其他第三方的JavaScript 库。进入Firebug Dom 选项卡观察,位于window 对象下面存放的变量数以百计,这些变量正是Ajax 库所带来到JavaScript 顶层全局环境的。JavaScript 是一门带有变量作用域的语言,任何一个变量若不加var 则可表示为一个全局成员,就加入在window 对象(即全局空间)下。

Ext 库并没有使用太多的全局变量在里面。任何一个它的类均安排在“Ext 对象底下,所以说整个框架只使用了一个全局变量Ext (如 图)。

《Ext详解与实践 v3》阅读补充资料:分配命名空间

 

  Firebug 跟踪JavaScript 全局空间

命名空间(Namespace) 表示标识符(Identifier) 的上下文(Context) 。一个标识符可在多个命名空间中定义,它在不同命名空间中的含义是互不相干的。这样,在一个新的命名空间中可定义任何标识符,它们不会与任何已有的标识符发生冲突,因为已有的定义都处于其他命名空间中。把实现的代码安排在一个特定的命名空间中,由各个类或单例构成,这样的JavaScript 编码风格不仅有良好的组织,直观可维护的优点,而且还能有避免它方代码干扰、窜改的好处。“为变量创建其命名空间,这样类就有了“安身之所”,不是飘荡四处的“全局变量。”(摘自API 文档)”。

提示: 笔者有一次就 Ext API 翻译的问题与参与人员发生小误会,有两份文件都是 DataField.js ,分别在不同的包中,一个是 /widget/DataField.js ;另外一个是 /widget/form/DataField.js 。但笔者误认为“未翻译的”当作“已翻译的”,这样大家碰头时就发生误会了。看来还真是命名空间相冲突而导致的结果,最后大家认真沟通下才把问题解释清楚。

使用Ext.ns() 可以实现简单的命名空间声明方式,其全称是Ext.namespace() Ext.ns() 用法如 所示:

/* Ext.namespace会创建下列对象,若不存在的话 */ Ext.namespace('App', 'App.panel', 'App.data'); /* // 等价于注释的语句 if (!App)     App = {}; if (!App.form)     App.form = {}; if (!App.data)     App.data = {}; */   /* 定义App.form包内部的新类SamplePanel */ App.panel.SamplePanel = Ext.extend(Ext.Panel, {     initComponent: function(){         /*component configuration code here! */         App.form.SamplePanel.superclass.call(this);     } });

Ext.namespace() 传入的参数中不能包含 ECMAScript 关键字,例如“ com.extjs.long 中的 long 是关键字,不能被 ns 方法执行。

Ext.namespace() 方法的关键地方之一是利用了eval 函数解析字符串为对象,若在一些不支持eval() 函数环境(如Adobe AIR 的安全沙箱下),可参考YUI 库的namespace() 方法,主要原理是JavaScript 的对象“索引式”声明增加Hash 表内元素,缺点是有第一个因子项的限制,因为该方法中须明确命名空间的第一个因子项。

// Yahoo! UI namespce方法源码 namespace = function() {         YAHOO = {};  // YAHOO是全局变量         var a=arguments, o = null, i, j, d;         // 遍历所传入的参数。JavaScript的参数具有参数个数不确定性         for (i=0; i<a.length; i=i+1) {             d = a[i].split(".");// 返回数组,每个字符串以.分割开后,成为数组的元素             o = YAHOO;             // 规定所有的命名空间均以YAHOO开头,如果依据显式声明则忽略             for (j=(d[0] == "YAHOO") ? 1 : 0; j<d.length; j=j+1) {                 o[d[j]]=o[d[j]] || {}; // 跳过当前已经存在的对象                 o=o[d[j]]; // 移位到数组的下一个元素             }         }         return o; }

此处披露的内容是《Ext详解与实践》 的补充内容,完整的资料敬请参阅《Ext详解与实践》 一书(覆盖包含2.2/3.03的版本)的全面介绍。

上一篇:【OSS对象存储】上传OSS提示callbackfailed问题


下一篇:TIF、JPG图片手动添加地理坐标的方法