博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript的namespace
阅读量:4927 次
发布时间:2019-06-11

本文共 4111 字,大约阅读时间需要 13 分钟。

 

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

 

从事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);
}
上面就是在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();
 
 

没有框架的程序,像是刀耕火种,杂乱无章仅可果腹;

使用框架的程序,就像种田,尽管单一,效益却不错;

那么写框架,则就是开荒了。呵呵....

人类,也就是这么走过来的。

 

关于JavaScript 的框架,网上似乎不大多,最知名的,也就是个EXT了,很不错,华丽,强大,不过学着用点麻烦;宁愿自己写一个,写了N天,实在头痛,N多内容,的确工作量不小,做下整理....

首选,做个广告,把这段时间对我帮助很大的几个网站公布如下:

           纯中文,对WEB标准的模型和参考文档都很全;数据量不大,却很精准的。

            纯英文,Mozilla 开发人员中心,为了兼容,英文也啃了。

              中英参半,著名的独裁者微软的开发人员网络;

至于百度,Google等,提名即可,以下进入正题。

我的 xSystem 的测试版就要出炉了,按照版本规则和服务器上的号码显示,当前应该称呼它为 xSystem Framework 1.0.28 beta 尽管它小的可怜;也有不少 BUG;呵呵...

 

要解决的第一个问题,关于命称空间(namespace)或叫包(package)结构;

       坦白讲,JavaScript 并不是一个完整的面像对像的语言,所谓的JavaScript 面像对像,不过是以面向对像的思想,以另外的手段去模拟;写习惯了java等语言的程序员,很习惯于这样的写法:

new a().b.c().d(e).f.g();

有些夸张,但是却是事实;我们要做的就是找到一种类似的方法,并非为了解决习惯问题,而是解决大量代码封装时面临的变量名等冲突和代码组织管理等问题。

郭熟悉JavaScript 中的人,都知道 javascript中对像的一大特点,几乎即任何时候,都可以向一个对像添加属性和方法;

如:

function ClassA(){} // 声明一个类 ClassA;var objA = new ClassA(); // 创建一个类的实例. objA;objA.name = "classA"; // 为 对像 objA 添加name属性;WScript.Echo(objA.name); // 打出添加的objA的name属性

复杂一点若name也是一个对像:

function name(){ // 把名子拆成姓和名两部分; this.firstname = "class";? this.lastname = "A"; function getfullName(){   return this.firstname + this.lastname;  }  this.getfullName = getfullName; }var objB = new ClassA();objB.name = new name(); WScript.Echo(objB.name.getfullName());

我需要更简单的写法:

我们实现了我们所需要的,但是的确这种写法又臭又长,况且我们并不需要反复的声明对像,然后反复的实例化他们,古怪的javaScript为我们提供了不写构造函数,而直接写出对像的方法即 {} 花括号;
简单的写法:
var ObjC = {name:{firstname:"Class",lastname:"A",getfullName:function(){return this.firstname+this.lastname}}}
WScript.Echo(objC.name.getfullName());

以上,即是名称空间的实现方法,即利用javascript对像的扩展性,对像的属性是一个对像,属性的属性还是一个对像;以此类推去构建我们所需要的结果:

一段完整的例子:

// 声明框架根空间对像var xSystem = {author:"戏得散人",blog:"http://shizhong8841.blog.163.com"};// 提供空间内的全局堆栈;xSystem.globle = {};// 为 globle 添加 get 和set 方法, value 可以是任意类型的对像;xSystem.set = function(name,value){ xSystem.globle[name]=value;}// 根据名字返回globle空间中的对像;xSystem.get = function(name){ return xSystem.globle[name];}// 把globle空间中的一个对像置空并删除;xSystem.setNull = function(name){ xSystem.globle[name] = null;    delete(xSystem. globle[name]);}xSystem.set("key",100);alert(xSystem.get("key"));xSystem.setNull("key");alert(xSystem.get("key"));
 
转自http://blog.chinaunix.net/uid-20657416-id-1905453.html
http://blog.chinaunix.net/uid-20657416-id-1905454.html

转载于:https://www.cnblogs.com/yufu/articles/3865460.html

你可能感兴趣的文章
注册维))基))百))科))
查看>>
eclipse 中手动安装 subversive SVN
查看>>
react常用语法
查看>>
【json的使用】
查看>>
ural 1519 Formula 1(插头dp)
查看>>
序列化和反序列化
查看>>
Web服务器Nginx多方位优化策略
查看>>
作业六:三层神经网络调参
查看>>
Java中的hashcode方法
查看>>
OpenCV学习 7:图像形态学:腐蚀、膨胀
查看>>
软件需求与分析课堂讨论一
查看>>
js添加var和不加var区别
查看>>
时钟程序
查看>>
无法识别的配置节log4net的(Unrecognized configuration section log4net)
查看>>
个人项目-小学四则运算 “软件”之初版
查看>>
cocos2d-html5学习笔记——创建持续性动作
查看>>
软件工程心得体会
查看>>
typedef typedef struct的使用
查看>>
Log4Net各参数API
查看>>
接收发送给服务器的Post请求
查看>>