JavaScript模块化
一、概述
JavaScript代码为了提高代码的可重用性,也可以进行模块化。不过JavaScript的模块化并没有像java等语言一样有语言级别的支持,它的模块化更多的是一种代码书写的规范。
二、以对象作为命名空间
var sets={};//定义一个命名空间
sets.Set=sets.AbstractEnumerableSet.extend(...);//在命名空间sets中定义一个类Set
var set=new sets.Set(23);//初始化一个Set对象,使用类的全限定名
var Set=sets.Set;//导入sets.Set类
var s=new Set(1,2,3);//导入类后,不再需要使用全限定名,直接使用类名就可以了
嵌套命名空间:
var collections;//定义或者重定义顶级命名空间名:collections
if(!collections)
collections={};
collections.sets={};//在collections命名空间中定义另一命名空间sets
collections.sets.AbstractSet=function(){...}//在命名空间sets中定义类
var sets=collections.sets;//导入整个命名空间,使得命名空间下所有类都可以使用
约定:一个模块作为一个js文件,命名空间以文件夹的形式组织,这个和java的约定是一样的。和java不同的是,一个java文件一般对应一个类,但是一个js文件一般对应一个命名空间,即一个模块,改模块中可以包含很多个类,也就是一个js文件包含很多个类,这些类在同一个命名空间下。
三、函数定义域作为私有命名空间
一个模块里包含函数,类,属性和一些方法给调用者调用,然而,在有些情况下,我们希望一个模块里的成员是只能在模块内部被调用,模块的使用者是无法调用得到的。
为了达到这个目的,我们可以把模块定义在一个函数里面,因为在一个函数里面定义的变量和函数只在这个函数里有效,在外部是看不到的。
例子一:
var Set=(function invocation(){
function Set(){
this.values={};
this.n=0;
this.add.apply(this,arguments);//公有函数,模块使用者可以调用
}
Set.prototype.contains=function(value){...};
Set.prototype.add=function(){...};
function v2s(val){...}//私有函数,只能在模块内部调用
var nextId=1;//私有变量
return Set;
}());
例子二:使用函数返回值导出命名空间里的多个类
collections.sets=(function namespace(){
//在这里定义命名空间里的类...
return {AbstractSet:AbstractSet,ArraySet:ArraySet,SingletonSet:SingletonSet};//导出该命名空间里的接口给外面调用
}());
例子三:使用new导出命名空间里的多个类,不需要return语句
collections.sets=(new function namespace(){
//在这里定义命名空间的类...
this.AbstractSet=AbstractSet;this.ArraySet=ArraySet;this.SingletonSet=SingletonSet;
}());
例子四:先定义空间对象,然后给对象赋值导出空间的类
var collections.sets={};
(function namespace(){
//在这里定义命名空间的类...
collections.sets.AbstractSet=AbstractSet;collections.sets.ArraySet=ArraySet;collections.sets.SingletonSet=SingletonSet;
}());