`

javascript实现命名空间

阅读更多

在小规模的脚本开发中,有时候并不值得去引用命名空间,因为会带来某种程度的复杂性;但是当在同一个网页里引入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简单实现命名空间效果.docx

    JavaScript创建命名空间(namespace)的最简实现

    JavaScript创建命名空间(namespace)通过自定义函数进行类型判断、数组遍历、函数执行等相关操作来实现命名空间的功能,需要的朋友可以参考一下

    JavaScript 命名空间 使用介绍

    使用JavaScript实现命名空间就没有这么舒服了,Javascript只有函数作用域,什么块儿啊、神马文件啊统统都认为是一个命名空间的,有时候因为一些重名问题导致的错误让人莫名其妙,难以调试解决

    javascript简单实现命名空间效果

    Javascript原生并不支持命名空间,需要变通来实现。 在我们创建一个JavaScript库时,命名空间就显得举足轻重了,我们可以将组成这个JavaScript库的零散的JavaScript文件(*.js)封装在命名空间中,而无须定义全局的...

    自定义命名空间组件

    用源生的javascript实现一个命名空间的组件类,可以一次创建多个命名空间。

    在JavaScript中实现命名空间

    在引入命名空间之前,一个令开发人员头疼的问题就是如何防止函数名/类名和其他人的冲突,在一个公司内部项目组之间可以通过命名预定(比如加前缀等)解决这个问题,但是把视线放到整个软件开发领域,在当今协作开发...

    javascript实现相同事件名称,不同命名空间的调用方法

    主要介绍了javascript实现相同事件名称,不同命名空间的调用方法,涉及javascript命名空间及事件调用的技巧,需要的朋友可以参考下

    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....

    非常好的javascript原理资源,分享出来.zip

    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的对象实现

    js-qname 简单的QName(命名空间URI +本地名称)JavaScript的对象实现

    javascript 命名空间以提高代码重用性

    为此,在封装javascript组件库的时候,请使用命名空间来避免冲突。 将所有的方法和变量都要按包名类名的方式来写。 (这个时候写代码的感觉和封装java的util方法一样方便,呵呵) 由此,我的js库按如下方式封装。

    snake:Snake 的 JavaScript 实现

    非常饿的毛毛虫 游戏“Snake”的 JavaScript 实现,灵感来自 Eric Carle 的书“The Very Hungry Caterpillar”。 全局命名空间、面向对象的 JavaScript jQuery 处理事件 自定义 CSS

    非常好的js项目资源,分享出来.zip

    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....

    JavaScript权威指南(第6版)

    8.5 作为命名空间的函数 8.6 闭包 8.7 函数属性、方法和构造函数 8.8 函数式编程 第9章 类和模块 9.1 类和原型 9.2 类和构造函数 9.3 JavaScript中Java式的类继承 9.4 类的扩充 9.5 类和类型 9.6 JavaScript中的面向...

    JavaScript模式中文[pdf] 百度云

     命名空间模式  声明依赖关系  私有属性和方法  模块模式  沙箱模式  静态成员  对象常量  链模式  method()方法  小结  第6章 代码复用模式  传统与现代继承模式的比较  使用类式继承时的预期结果  ...

Global site tag (gtag.js) - Google Analytics