在小规模的脚本开发中,有时候并不值得去引用命名空间,因为会带来某种程度的复杂性;但是当在同一个网页里引入10多个js文件之后,各js中的同名函数就很容易冲突了。比如xxx库里写了个addCssStyle方法,yyy类库里也写了个addCssStyle方法,而这两个方法的具体实现又有一定差别。那么同时引用这两个组件的时候,函数冲突之后导致页面效果发生变化,调试和修改都是非常痛苦的,如果为了避免冲突,而放弃引用一些优秀的组件,那更是让人郁闷的事情。为此,在封装javascript组件库的时候,请使用命名空间来避免冲突。将所有的方法和变量都要按包名类名的方式来写。(这个时候写代码的感觉和封装java的util方法一样方便,呵呵)
所以,请记住:请为你封装的JavaScript库加上命名空间以提高代码重用性。
但是JavaScript原生并不支持命名空间,需要变通来实现。
在JavaScript中,所有的对象(或者称类型,例如Boolean,Array,Function)都可以认为是一个关联数组。关联数组中的对象可以使用点(.)进行引用,这样我们可以利用关联数组变相地实现命名空间。首先声明一个关联数组作为根,因为页面声明的对象都是window这个变量的成员,所以一般命名空间的实现都以window为根。当向window申请a.b.c的命名空间时,首先在window中查看是否存在a这个成员,如果没有则在window下新建一个名为a的空关联数组,如果已经存在a,则继续在window.a中查看b是否存在,以此类推。下面分别是Atlas和YUI中的实现方法。
//Atlas命名空间的实现方法 Function.registerNamespace =function(namespacePath){ //以window为根 var rootObject =window; //对命名空间路径拆分成数组 var namespaceParts =namespacePath.split('.'); for (var i =0;i <namespaceParts.length;i++) { var currentPart =namespaceParts[i]; //如果当前命名空间下不存在,则新建一个Object对象,等效于一个关联数组。 if (!rootObject[currentPart]) { rootObject[currentPart]=new Object(); } rootObject =rootObject[currentPart]; } }
Atlas的实现通俗易懂。Javascrip中rootObject[currentPart]=new Object();和rootObject[currentPart]={};是等效的两种写法。
//YUI命名空间的实现方法 var YAHOO = window.YAHOO || {}; YAHOO.namespace = function(ns) { if (!ns || !ns.length) { return null; } var levels = ns.split("."); var nsobj = YAHOO; //如果申请的命名空间是在YAHOO下的,则必须忽略它,否则就成了YAHOO.YAHOO了 for (var i=(levels[0] == "YAHOO") ? 1 : 0; i<levels.length; ++i) { //如果当前命名空间下不存在,则新建一个关联数组。 nsobj[levels[i]] = nsobj[levels[i]] || {}; nsobj = nsobj[levels[i]]; } //返回所申请命名空间的一个引用; return nsobj; };
YUI的实现带有一点C风格,nsobj[levels[i]] = nsobj[levels[i]] || {};这句相比于Atlas显得要晦涩一些。
比较一下Atlas和YUI的实现,YUI稍微好一些,因为YUI中申请命名空间的时候会返回一个引用,可以赋值给一个变量,这就相当于声明了该名称空间的一个别名,编码会方便不少。YUI把所有申请的命名空间都放在了window.YAHOO下面,这样有什么好处呢?假如Yahoo和其他公司有合作关系,需要嵌入对方的脚本时,这样能保证它自己编写的代码都在YAHOO这个空间下面,而其他公司不大可能在这个空间下面编码,就基本不会出现命名冲突的情况。我觉得这个做法好,是因为在不对等的合作关系中,要求对方去修改代码来适应你的应用是不现实的,YUI的实现考虑了这点。
还有一点,所有的命名空间都放在window.YAHOO下是最好最合理的做法嘛?在大量应用动态效果的页面中,这势必要维护一个超大的关联数组。关联数组本质是哈希数组,检索数组成员的开销可以忽略不计,但是window.YAHOO承载的东西太多太复杂,这是否违背了大道至简的原则?有没有更好的办法?
例子:
//1、命名空间注册工具类 var Namespace = new Object(); Namespace.register = function(path) { var arr = path.split("."); var ns = ""; for ( var i = 0; i < arr.length; i++) { if (i > 0) ns += "."; ns += arr[i]; eval("if(typeof(" + ns + ") == 'undefined') " + ns + " = new Object();"); } } //2、注册命名空间 com.cjm.ui Namespace.register("com.cjm.ui"); //3、使用命名空间 com.cjm.ui.TreeGrid = function() { this.sayHello = function(name) { alert("Hello " + name); } } var t = new com.cjm.ui.TreeGrid(); t.sayHello("uid");
相关推荐
javascript简单实现命名空间效果.docx
JavaScript创建命名空间(namespace)通过自定义函数进行类型判断、数组遍历、函数执行等相关操作来实现命名空间的功能,需要的朋友可以参考一下
使用JavaScript实现命名空间就没有这么舒服了,Javascript只有函数作用域,什么块儿啊、神马文件啊统统都认为是一个命名空间的,有时候因为一些重名问题导致的错误让人莫名其妙,难以调试解决
Javascript原生并不支持命名空间,需要变通来实现。 在我们创建一个JavaScript库时,命名空间就显得举足轻重了,我们可以将组成这个JavaScript库的零散的JavaScript文件(*.js)封装在命名空间中,而无须定义全局的...
用源生的javascript实现一个命名空间的组件类,可以一次创建多个命名空间。
在引入命名空间之前,一个令开发人员头疼的问题就是如何防止函数名/类名和其他人的冲突,在一个公司内部项目组之间可以通过命名预定(比如加前缀等)解决这个问题,但是把视线放到整个软件开发领域,在当今协作开发...
主要介绍了javascript实现相同事件名称,不同命名空间的调用方法,涉及javascript命名空间及事件调用的技巧,需要的朋友可以参考下
命名空间是通过为项目或库创建一个全局对象,然后将所有功能添加到该全局变量中。通过减少程序中全局变量的数量,实现单全局变量,从而在具有大量函数、对象和其他变量的情况下不会造成全局污染,同时也避免了命名...
主要介绍了JavaScript命名空间模式,结合实例形式分析了javascript命名空间模式的相关概念、原理、实现方法及操作注意事项,需要的朋友可以参考下
6.javascript 命名空间 Oject-Oriented 1.JavaScript Expressive 2. Interfaces 3.Introduction 4. Inheritance 5.AOP Jquery [jQuery][9] [jQuery架构设计与实现][10] [jQuery选择器库][11] [zepto][12] 1....
6.javascript 命名空间 Oject-Oriented 1.JavaScript Expressive 2. Interfaces 3.Introduction 4. Inheritance 5.AOP Jquery [jQuery][9] [jQuery架构设计与实现][10] [jQuery选择器库][11] [zepto][12] 1....
js-qname 简单的QName(命名空间URI +本地名称)JavaScript的对象实现
为此,在封装javascript组件库的时候,请使用命名空间来避免冲突。 将所有的方法和变量都要按包名类名的方式来写。 (这个时候写代码的感觉和封装java的util方法一样方便,呵呵) 由此,我的js库按如下方式封装。
非常饿的毛毛虫 游戏“Snake”的 JavaScript 实现,灵感来自 Eric Carle 的书“The Very Hungry Caterpillar”。 全局命名空间、面向对象的 JavaScript jQuery 处理事件 自定义 CSS
6.javascript 命名空间 Oject-Oriented 1.JavaScript Expressive 2. Interfaces 3.Introduction 4. Inheritance 5.AOP Jquery [jQuery][9] [jQuery架构设计与实现][10] [jQuery选择器库][11] [zepto][12] 1....
8.5 作为命名空间的函数 8.6 闭包 8.7 函数属性、方法和构造函数 8.8 函数式编程 第9章 类和模块 9.1 类和原型 9.2 类和构造函数 9.3 JavaScript中Java式的类继承 9.4 类的扩充 9.5 类和类型 9.6 JavaScript中的面向...
命名空间模式 声明依赖关系 私有属性和方法 模块模式 沙箱模式 静态成员 对象常量 链模式 method()方法 小结 第6章 代码复用模式 传统与现代继承模式的比较 使用类式继承时的预期结果 ...