威尼斯www.9778.com-威尼斯正版官方网站

在 JavaScript 中实现名称空间

日期:2020-01-23编辑作者:编程人生

在引入命名空间之前,一个令开发人员头疼的问题就是如何防止函数名/类名和其他人的冲突,在一个公司内部项目组之间可以通过命名预定(比如加前缀等)解决这个问题,但是把视线放到整个软件开发领域,在当今协作开发相当盛行的时代,这个问题却依然存在。在使用多个第三方框架或类库的时候,你唯一能作的就是祈祷它们的命名不要冲突,如果真正发生这种灾难的话,你唯一能作的就是放弃其中一个(注:可能是我孤陋寡闻,呵呵)。命名空间的引入相当程度上解决了这个问题,当然,如果你使用的命名空间和其他公司不幸一样,而对方又是微软、SUN 等大佬,那恭喜你,呵呵 @_@!

注:好久没写了,今天把我在公司内网写的文章拷一份,出来露露脸,刚转Web开发,所以开始学JavaScript!

从事 Web 开发不可避免要接触 JavaScript,目前最新版本的 JavaScript 还是不支持命名空间,所以命名冲突的问题凸显无疑,想象一下你引用了两个 js 文件,却发现由于命名问题导致你不得不放弃其中一个,从而导致多写了许多代码,无疑是十分令人沮丧的。在 JavaScript 新版本引入命名空间概念之前,发扬自立更生精神和创造性是我们程序员的基本义务;-)

在引入命名空间之前,一个令开发人员头疼的问题就是如何防止函数名/类名和其他人的冲突,在一个公司内部项目组之间可以通过命名预定(比如加前缀等)解决这个问题,但是把视线放到整个软件开发领域,在当今协作开发相当盛行的时代,这个问题却依然存在。在使用多个第三方框架或类库的时候,你唯一能作的就是祈祷它们的命名不要冲突,如果真正发生这种灾难的话,你唯一能作的就是放弃其中一个(注:可能是我孤陋寡闻,呵呵)。命名空间的引入相当程度上解决了这个问题,当然,如果你使用的命名空间和其他公司不幸一样,而对方又是微软、SUN等大佬,那恭喜你,呵呵@_@!

实现前提:与 Delphi、C# 等语言不同,JavaScript 中的类并不是对象的定义,事实上 JavaScript 中并不存在真正的类,这里的类实际上是用函数模拟实现的,而 JavaScript 中的函数实际上是一个对象,因此在 JavaScript 中:一个类就是一个对象。这和传统概念概念极为不同,在 JavaScript 中,创建某个类的实例实际上就是将类(=对象,记住)复制了一份。看到这里,有点设计模式概念的应该就可以看出来了,在 JavaScript 中,类机制使用了原型(prototype)模式。

从事Web开发不可避免要接触JavaScript,目前最新版本的JavaScript还是不支持命名空间,所以命名冲突的问题凸显无疑,想象一下你引用了两个js文件,却发现由于命名问题导致你不得不放弃其中一个,从而导致多写了许多代码,无疑是十分令人沮丧的。在JavaScript新版本引入命名空间概念之前,发扬自立更生精神和创造性是我们程序员的基本义务;-)

实现原理:既然看清楚了类的本质,那么问题就简单了,如果将 GEA 项目组所有 JS 类和函数作为属性放在名为 GEA 的对象里面,然后将 GEA 对象以属性的方式放在名为 Grandsoft 对象里面不就可以达到我们的目的,比如 Grandsoft.GEA.Person 实际上是在 Grandsoft 对象的属性 GEA(也是一个对象)中的类 Person(还是一个对象)。

实现前提:与Delphi、C#等语言不同,JavaScript中的类并不是对象的定义,事实上JavaScript中并不存在真正的类,这里的类实际上是用函数模拟实现的,而JavaScript中的函数实际上是一个对象,因此在JavaScript中:一个类就是一个对象。这和传统概念概念极为不同,在JavaScript中,创建某个类的实例实际上就是将类(=对象,记住)复制了一份。看到这里,有点设计模式概念的应该就可以看出来了,在JavaScript中,类机制使用了原型(prototype)模式。

实现非常简单,整个命名空间机制的实现不超过 20 行代码,分析如下:

实现原理:既然看清楚了类的本质,那么问题就简单了,如果将GEA项目组所有JS类和函数作为属性放在名为GEA的对象里面,然后将GEA对象以属性的方式放在名为Grandsoft对象里面不就可以达到我们的目的,比如Grandsoft.GEA.Person实际上是在Grandsoft对象的属性GEA(也是一个对象)中的类Person(还是一个对象)。

// 声明一个全局对象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);
}

实现非常简单,整个命名空间机制的实现不超过20行代码,分析如下:

上面就是在 JavaScript 中模拟命名空间机制的完整实现,使用方式如下:

图片 1// 声明一个全局对象Namespace,用来注册命名空间
图片 2Namespace = new Object();
图片 3
图片 4// 全局对象仅仅存在register函数,参数为名称空间全路径,如"Grandsoft.GEA"
图片 5Namespace.register = function(fullNS)
图片 6图片 7图片 8{
图片 9    // 将命名空间切成N部分, 比如Grandsoft、GEA等
图片 10    var nsArray = fullNS.split('.');
图片 11    var sEval = "";
图片 12    var sNS = "";
图片 13    for (var i = 0; i < nsArray.length; i++)
图片 14图片 15    图片 16{
图片 17        if (i != 0) sNS += ".";
图片 18        sNS += nsArray[i];
图片 19        // 依次创建构造命名空间对象(假如不存在的话)的语句
图片 20        // 比如先创建Grandsoft,然后创建Grandsoft.GEA,依次下去图片 21
图片 22        sEval += "if (typeof(" + sNS + ") == 'undefined') " + sNS + " = new Object();"
图片 23    }
图片 24    if (sEval != "") eval(sEval);
图片 25}图片 26

// 注册命名空间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();

上面就是在JavaScript中模拟命名空间机制的完整实现,使用方式如下:

哈哈,简单吧,这么简单的代码我就不多说了,大家自己看着玩吧,其实我有点懒,呵呵 @_@!!!

图片 27// 注册命名空间Grandsoft.GEA, Grandsoft.GCM
图片 28Namespace.register("Grandsoft.GEA");
图片 29Namespace.register("Grandsoft.GCM");
图片 30
图片 31// 在Grandsoft.GEA命名空间里面声明类Person
图片 32Grandsoft.GEA.Person = function(name, age)
图片 33图片 34图片 35{
图片 36    this.name = name;
图片 37    this.age = age;
图片 38}
图片 39
图片 40// 给类Person添加一个公共方法show()
图片 41Grandsoft.GEA.Person.prototype.show = function()
图片 42图片 43图片 44{
图片 45    alert(this.name + " is " + this.age + " years old!");
图片 46}
图片 47
图片 48// 演示如何使用类Person
图片 49var p = new Grandsoft.GEA.Person("yanglf", 25);
图片 50p.show();图片 51

相关阅读

哈哈,简单吧,这么简单的代码我就不多说了,大家自己看着玩吧,其实我有点懒,呵呵@_@!!!

  • 一起学 Microsoft AJAX Library-Type 类

本文由威尼斯www.9778.com发布于编程人生,转载请注明出处:在 JavaScript 中实现名称空间

关键词:

如何做兼容各浏览器的垂直居中-背景在窗口中

如何做兼容各浏览器的垂直居中-背景在窗口中 如何做兼容各浏览器的垂直居中-div在窗口中 学习资料 如何做兼容...

详细>>

一起学 Microsoft AJAX Library-DomEvent

一起学 Microsoft AJAXLibrary-介绍 一起学 Microsoft AJAX Library-Array类型扩展 一起学 Microsoft AJAX Library-Boolean 和 Date类型扩...

详细>>

一起学 Microsoft AJAX Library-Sys.Net.WebRequest

if (Sys.Browser.agent == Sys.Browser.InternetExplorer) {     alert("IE"); } else if (Sys.Browser.agent == Sys.Browser.Firefox) {     alert("Firef...

详细>>

一起学 Microsoft AJAX Library-Array 类型扩展

一起学 Microsoft AJAXLibrary-介绍 一起学 Microsoft AJAX Library-Array类型扩展 一起学 Microsoft AJAX Library-Boolean 和 Date类型扩...

详细>>