在JavaScript中实现命名空间
来源:互联网 发布:重庆进出口贸易数据 编辑:程序博客网 时间:2024/05/23 18:31
在引入命名空间之前,一个令开发人员头疼的问题就是如何防止函数名/类名和其他人的冲突,在一个公司内部项目组之间可以通过命名预定(比如加前缀等)解决这个问题,但是把视线放到整个软件开发领域,在当今协作开发相当盛行的时代,这个问题却依然存在。在使用多个第三方框架或类库的时候,你唯一能作的就是祈祷它们的命名不要冲突,如果真正发生这种灾难的话,你唯一能作的就是放弃其中一个(注:可能是我孤陋寡闻,呵呵)。命名空间的引入相当程度上解决了这个问题,当然,如果你使用的命名空间和其他公司不幸一样,而对方又是微软、SUN等大佬,那恭喜你,呵呵@_@!
var YAHOO = window.YAHOO || {};
YAHOO.namespace = function(ns) {
if (!ns || !ns.length) {
return null;
}
var levels = ns.split(".");
var nsobj = YAHOO;
// YAHOO is implied, so it is ignored if it is included
for (var i=(levels[0] == "YAHOO") ? 1 : 0; i<levels.length; ++i) {
nsobj[levels[i]] = nsobj[levels[i]] || {};
nsobj = nsobj[levels[i]];
}
return nsobj;
};
YAHOO.extend = function(subclass, superclass) {
var f = function() {};
f.prototype = superclass.prototype;
subclass.prototype = new f();
subclass.prototype.constructor = subclass;
subclass.superclass = superclass.prototype;
if (superclass.prototype.constructor == Object.prototype.constructor) {
superclass.prototype.constructor = superclass;
}
};
YAHOO.namespace("util");
YAHOO.namespace("widget");
YAHOO.namespace("example");
从事Web开发不可避免要接触JavaScript,目前最新版本的JavaScript还是不支持命名空间,所以命名冲突的问题凸显无疑,想象一下你引用了两个js文件,却发现由于命名问题导致你不得不放弃其中一个,从而导致多写了许多代码,无疑是十分令人沮丧的。在JavaScript新版本引入命名空间概念之前,发扬自立更生精神和创造性是我们程序员的基本义务;-)
实现前提:与Delphi、C#等语言不同,JavaScript中的类并不是对象的定义,事实上JavaScript中并不存在真正的类,这里的类实际上是用函数模拟实现的,而JavaScript中的函数实际上是一个对象,因此在JavaScript中:一个类就是一个对象。这和传统概念概念极为不同,在JavaScript中,创建某个类的实例实际上就是将类(=对象,记住)复制了一份。看到这里,有点设计模式概念的应该就可以看出来了,在JavaScript中,类机制使用了原型(prototype)模式。
实现原理:既然看清楚了类的本质,那么问题就简单了,如果将GEA项目组所有JS类和函数作为属性放在名为GEA的对象里面,然后将GEA对象以属性的方式放在名为Grandsoft对象里面不就可以达到我们的目的,比如Grandsoft.GEA.Person实际上是在Grandsoft对象的属性GEA(也是一个对象)中的类Person(还是一个对象)。
实现非常简单,整个命名空间机制的实现不超过20行代码,分析如下:
// 声明一个全局对象Namespace,用来注册命名空间
Namespace = new Object();
// 全局对象仅仅存在register函数,参数为名称空间全路径,如"Grandsoft.GEA"
Namespace.register = function(fullNS)
{
// 将命名空间切成N部分, 比如Grandsoft、GEA等
var nsArray = fullNS.split('.');
var sEval = "";
var sNS = "";
for (var i = 0; i < nsArray.length; i++)
{
if (i != 0) sNS += ".";
sNS += nsArray[i];
// 依次创建构造命名空间对象(假如不存在的话)的语句
// 比如先创建Grandsoft,然后创建Grandsoft.GEA,依次下去
sEval += "if (typeof(" + sNS + ") == 'undefined') " + sNS + " = new Object();"
}
if (sEval != "") eval(sEval);
}
Namespace = new Object();
// 全局对象仅仅存在register函数,参数为名称空间全路径,如"Grandsoft.GEA"
Namespace.register = function(fullNS)
{
// 将命名空间切成N部分, 比如Grandsoft、GEA等
var nsArray = fullNS.split('.');
var sEval = "";
var sNS = "";
for (var i = 0; i < nsArray.length; i++)
{
if (i != 0) sNS += ".";
sNS += nsArray[i];
// 依次创建构造命名空间对象(假如不存在的话)的语句
// 比如先创建Grandsoft,然后创建Grandsoft.GEA,依次下去
sEval += "if (typeof(" + sNS + ") == 'undefined') " + sNS + " = new Object();"
}
if (sEval != "") eval(sEval);
}
上面就是在JavaScript中模拟命名空间机制的完整实现,使用方式如下:
// 注册命名空间Grandsoft.GEA, Grandsoft.GCM
Namespace.register("Grandsoft.GEA");
Namespace.register("Grandsoft.GCM");
// 在Grandsoft.GEA命名空间里面声明类Person
Grandsoft.GEA.Person = function(name, age)
{
this.name = name;
this.age = age;
}
// 给类Person添加一个公共方法show()
Grandsoft.GEA.Person.prototype.show = function()
{
alert(this.name + " is " + this.age + " years old!");
}
// 演示如何使用类Person
var p = new Grandsoft.GEA.Person("yanglf", 25);
p.show();
Namespace.register("Grandsoft.GEA");
Namespace.register("Grandsoft.GCM");
// 在Grandsoft.GEA命名空间里面声明类Person
Grandsoft.GEA.Person = function(name, age)
{
this.name = name;
this.age = age;
}
// 给类Person添加一个公共方法show()
Grandsoft.GEA.Person.prototype.show = function()
{
alert(this.name + " is " + this.age + " years old!");
}
// 演示如何使用类Person
var p = new Grandsoft.GEA.Person("yanglf", 25);
p.show();
也可以看下yui的命名空间方式,还有prototype
比较优秀的js framework都有命名空间的概念
比较优秀的js framework都有命名空间的概念
yui的命名空间和继承机制
var YAHOO = window.YAHOO || {};
YAHOO.namespace = function(ns) {
if (!ns || !ns.length) {
return null;
}
var levels = ns.split(".");
var nsobj = YAHOO;
// YAHOO is implied, so it is ignored if it is included
for (var i=(levels[0] == "YAHOO") ? 1 : 0; i<levels.length; ++i) {
nsobj[levels[i]] = nsobj[levels[i]] || {};
nsobj = nsobj[levels[i]];
}
return nsobj;
};
YAHOO.extend = function(subclass, superclass) {
var f = function() {};
f.prototype = superclass.prototype;
subclass.prototype = new f();
subclass.prototype.constructor = subclass;
subclass.superclass = superclass.prototype;
if (superclass.prototype.constructor == Object.prototype.constructor) {
superclass.prototype.constructor = superclass;
}
};
YAHOO.namespace("util");
YAHOO.namespace("widget");
YAHOO.namespace("example");
了解.NET的同学都知道,.NET的主命名空间是System,其下有:
System.Web
System.Windows
System.Drawing
System.IO
等等子命名空间或类.
著名的javascript框架dojo,就采用了命名空间类似的方法管理内部的js模块。
我那项目的框架完全自己编写,也采用了.NET类似的方法进行命名空间规划。
顶层命名空间 System
可以这样声明该命名空间:
var System = new Object();
增加子命名空间 System.IO
System.IO = new Object();
增加IO命名空间的类FileStream
System.IO.FileStream = function(){
return null;
};
这样,一个System.IO.FileStream 命名空间&类就完成了。
如果需要实例化FileStream,则如下:
var fs = new System.IO.FileStream();
0 0
- 在JavaScript中实现命名空间
- 在JavaScript中实现命名空间
- 在JavaScript中实现命名空间
- 在JavaScript中实现命名空间
- 在JavaScript中实现命名空间
- 在JavaScript中实现命名空间
- 在JavaScript中实现命名空间
- 在JavaScript中实现命名空间
- 在JavaScript中实现命名空间
- JavaScript中实现命名空间
- javascript命名空间的实现
- 在JavaScript中创建命名空间的几种写法
- 在JavaScript中创建命名空间的几种写法
- 在JavaScript中创建命名空间的几种写法
- 在JavaScript中创建命名空间的几种写法
- 在JavaScript中创建命名空间的几种写法
- 在JavaScript中创建命名空间的几种写法
- 简单的实现JAVASCRIPT命名空间
- 安卓5.1最近任务栏滑块大小设置
- PHP,MySQL的安装与配置
- MFC编译错误之cannot open file '.\Debug\xxxDlg.sbr': No such file or directory
- Java进阶(极客)——反射机制(二)Field 对象的机制与实现
- PHP后台1:客户端(IOS/Android)GET请求PHP后台
- 在JavaScript中实现命名空间
- python 不是内部或外部命令
- 文件操作opendir()/readdir()/closedir()/stat() .
- send和WSASend区别
- 关于CLLocationManager无法定位的问题
- eclipse中Maven工程使用Tomcat7以上插件
- sysfs的应用-------使用sysfs控制闪关灯
- html5 cocos2d js Access-Control-Allow-Origin
- Android开发中Fragment的使用