命名空间
ExtJS的命名空间就是在window对象所提供的全局范围内建立相互独立的范围,概念上类似于Java的package。代码清单2-15演示了如何在window对象中创建一个名为helloMsg的变量。
代码清单2-15
- var helloMsg = 'Hi, there';
- console.info(helloMsg);
- console.info(window.helloMsg);
window属于全局性变量,因此,不需要指明window对象就可以使用helloMsg。这个示例是为了说明所有的变量都是存储在window对象下,而ExtJS所提供的命名空间机制也是利用这个特点,通过创建对象来实现命名空间:
代码清单2-16
- Ext.namespace('helloMsg');//也可以这样简写:Ext.ns('helloMsg')
- helloMsg = 'Hi, there.';
- console.info(helloMsg);
- console.info(window.helloMsg);
代码清单2-15与2-16会显示相同的文字信息。为了阐明这个概念,需要阅读Ext有关namespace的源代码。
代码清单2-17
- //摘自Ext.js中的namespace()
- namespace : function(){
- var o, d;
- // Ext.each()用来遍历(iterate)数据集合,下一节会介绍它的使用方法
- Ext.each(arguments, function(v) {
- d = v.split(".");
- o = window[d[0]] = window[d[0]] || {};
- Ext.each(d.slice(1), function(v2){
- oo = o[v2] = o[v2] || {};
- });
- });
- return o;
- }
代码清单2-17中的程序代码利用“.”作为变量的间隔符,创建的第一个对象会放在window里,第二个对象会放在第一个对象中,依此类推,利用“.”来创建包含多个对象的嵌套结构,命名空间就这样建立起来了,如代码清单2-18所示。
代码清单2-18
- Ext.namespace("org.aitch");
- console.info(typeof org); //object
- console.info(typeof org.aitch); //object
使用Ext.namespace()对“org.aitch”字符串进行解析,完成后变成两个对象:一个是org,另一个是org拥有的属性aitch。借助Ext.namespace(),实际开发时可以避免工作伙伴或是第三方开发商可能造成的命名冲突,如代码清单2-19所示。
代码清单2-19
- Ext.namespace("org.aitch.Person");
- Ext.namespace("org.bob.Person");
- org.aitch.Person = function(){
- this.firstname = "Aitch";
- this.lastname = "Chung";
- this.getInfo = function(){
- return "This dude is:"+this.firstname+" "+this.lastname;
- }
- }// eo org.aitch.Person
- org.bob.Person = function(){
- this.firstname = "Bob";
- this.lastname = "Chen";
- this.getInfo = function(){
- return "I'm "+this.firstname;
- }
- } // eo org.bob.Person
- var personA = new org.aitch.Person();
- var personB = new org.bob.Person();
- console.info(personA.getInfo()); //This dude is:Aitch Chung
- console.info(personB.getInfo()); //I'm Bob
代码清单2-19中定义了两个一模一样的Person类,借助Ext.namespace(),这两个类不会产生名命冲突。命名空间在团队开发时相当重要,尤其是当项目中包含第三方套件时。挑选适合自己团队的命名空间,可以domain name作为参考,按照domain name的倒序形式命名。由于命名空间是由对象模拟出来的,因此可以在其中放置全局变量及公共函数。在项目中可以创建这样的命名空间,从而在各个模块之间读取共享数据时使用,但应该限制为只读变量。如果模块之间要交换数据,最好还是使用事件机制或是将数据交给后台服务器管理。事件机制是下一章的重点,之后在开发项目实例时,会再讨论如何将数据交给后台服务器管理。