`

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

    以下是一些实现命名空间的常见方法: 1. **对象嵌套**: 在给定的示例中,`com.anyjava` 是一个命名空间,它通过对象嵌套的方式创建。`com` 是顶级命名空间,`anyjava` 是其下的子命名空间。通过这种方式,可以将...

    浅析JavaScript中命名空间namespace模式_.docx

    由于JavaScript没有像C#或Java那样的内置命名空间支持,开发者需要通过自定义的方式来实现类似的功能。本文将深入浅析JavaScript中的命名空间模式及其应用。 首先,命名空间的主要目的是限制全局变量的数量,因为...

    javascript创建命名空间的5种写法_.docx

    #### 三、通过闭包和对象实现命名空间 闭包可以用来保护命名空间内的私有变量和方法,同时也可以通过返回的对象来暴露公共接口。 **示例代码**: ```javascript var namespace = namespace || {}; namespace....

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

    在JavaScript中创建命名空间是为了避免全局变量污染以及更好地组织代码结构。命名空间可以将代码逻辑分隔成一个一个的模块,防止变量名或函数名发生冲突。在给定的文件信息中,提供了两种方法来实现创建命名空间的...

    WebApi返回xml格式时去除命名空间

    然而,在某些场景下,例如与JavaScript或简单的数据解析应用集成时,我们可能希望去掉这些命名空间以简化处理。 要实现这个目标,我们可以自定义一个XML序列化器,继承自`System.Xml.Serialization.XmlSerializer`...

    JavaScript创建命名空间的5种写法

    这种方法通过声明一个函数来实现命名空间,将变量和方法封装在函数内部。例如: ```javascript var NameSpace = NameSpace || {}; NameSpace.Hello = function() { this.name = 'world'; }; NameSpace.Hello....

    javascript创建命名空间的5种写法__1.docx

    JavaScript中的命名空间是一种组织代码的方式,它可以帮助我们避免全局变量冲突,提高代码的可维护性和安全性。以下是五种创建JavaScript命名空间的方法: 1. **通过函数(function)创建** 这种方法通常涉及定义一...

    javascript简单实现命名空间效果

    以下是一些关于如何在JavaScript中简单实现命名空间效果的知识点: 1. 命名空间定义:在JavaScript中,可以通过创建对象字面量的方式来定义命名空间。例如,可以创建一个全局对象,并在该对象下添加属性,这些属性...

    Javascript 命名空间模式

    在JavaScript这种没有原生命名空间支持的语言中,通过创建一个全局对象并将所有功能附加到这个对象下面,可以模拟实现类似命名空间的效果。这种方式通常用于大型项目或库,以保持代码的整洁和可维护性。 在描述中...

    js命名空间和闭包

    然而,JavaScript并没有原生支持命名空间,但它可以通过模拟实现,常见的方法有对象字面量、立即执行函数表达式(IIFE)和模块化(如CommonJS、ES6模块)等。 1. 对象字面量:这是一种创建命名空间的简单方式,通过...

    javascript自执行函数之伪命名空间封装法.docx

    ### JavaScript自执行函数之伪命名空间封装法 #### 一、引言 在现代Web开发中,JavaScript作为一种广泛使用的客户端脚本语言,其作用日益显著。为了提高代码的可维护性和安全性,开发者们不断探索新的编码技巧。...

    jquery命名空间模拟

    本篇文章将深入探讨如何在JavaScript中模拟jQuery的命名空间,以实现更有序、更安全的代码组织。 首先,我们需要理解JavaScript的命名空间是如何工作的。由于JavaScript本身没有内置的命名空间机制,我们通常通过...

    JavaScript 编程引入命名空间的方法

    JavaScript 命名空间实现方法 JavaScript 编程引入命名空间的方法是为了避免函数名相同的问题。在 JavaScript 中,没有命名空间的概念,需要使用对象来模拟命名空间。下面是一个基本的命名空间实现方法: 1. 定义...

    大的法师地方js命名空间

    总之,命名空间在JavaScript开发中扮演着至关重要的角色,尤其是在处理大型项目或实现代码模块化时。通过合理地创建和使用命名空间,可以有效地管理代码结构,避免命名冲突,提高代码的可读性和可维护性。在实际应用...

    自定义命名空间组件

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

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

    本文将深入讲解如何在JavaScript(特别是jQuery库)中实现相同事件名称,但通过命名空间调用不同功能的方法。 首先,理解命名空间的概念。在JavaScript中,命名空间是一种组织代码的方式,可以防止变量或函数名冲突...

    在JavaScript中实现命名空间

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

Global site tag (gtag.js) - Google Analytics