JavaScript中的模块实现方法有:
模块通常用来分离和组织项目中的代码单元。
对象字面量表示法中,一个对象被描述为一组包含在大括号({})中,以逗号分割的name/value对。 对象内的名称可以是字符串或者标识符,用冒号结尾。 最后一个name/value对后面不能加逗号。
var myObjectLiteral = {
variableKey:variableValue,
functionKey:function(){
//...
}
};
对象字面量不需要使用new关键字来进行实例化。 使用对象字面量表示的模块示例:
var myModule = {
// 对象字面量可以拥有属性
myProperty : "someValue",
// 对象字面量可以包含对象
myConfig : {
useCaching: true,
language: "en"
}
// 可以拥有方法
myMethod : function(){
console.log("this is a message from a method in mosule");
}
// 根据当前配置输出信息
myMethod2 : function(){
console.log("Caching is: " + this.myConfig.useCaching ? "enabled" : "disabled");
}
// 重写当前配置
myMethod3 : function(newConfig){
if(typeof newConfig === "object"){
this.myConfig = newConfig;
console.log(this.myConfig.language);
}
}
};
// 输出this is a message from a method in mosule
myModule.myMethod();
// 输出enable
myModule.myMethod2();
// 输出cn
myModule.myMethod3({
language: "cn",
useCaching : false
});
JavaScript中,Mosule模式用于模拟类的概念,这种方式能够使一个单独的对象拥有公有/私有方法和变量,从而屏蔽来自全局作用域的特殊部分。 可以使得函数名于页面其他脚本定义的函数冲突的可能性降低。
JavaScript中没有真正意义上的私有,因为它没有访问修饰符。因此需要使用函数作用域来模拟这一概念。 Module模式使用闭包封装“私有”状态和组织,它提供了一种包装混合私有/公有的方法和变量的表达式,防止其泄露到全局作用域。 通过闭包,暴露一个公有API,其他的部分维持在私有闭包中。
var testModule = (function(){
var counter = 0;
return {
incrementCounter: function(){
return ++counter;
},
resetCounter: function(){
console.log("counter value prior to reset: "+ counter);
counter = 0;
}
};
})();
// 用法:
//增加计数器
testModule.incrementCounter();
// 检查计数器并重置
// 输出:counter value prior to reset: 1
testModule.resetCounter();
// 输出:undefined
console.log(testModule.counter);
在这里,代码外部无法直接读取incrementCounter()或者resetCounter()。也无法访问其中的counter变量,这样它表现的就像一个私有变量。
var myNameSpace = (function(){
// 私有计数器变量
var myPrivateVar = 0;
// 记录所有参数的私有函数
var myPrivateMethod = function(foo){
console.log(foo);
};
return {
//公有变量
myPublicVar : "foo",
myPublicFunction : function(bar){
// 私有变量自增
myPrivateVar++;
// 传入bar调用私有方法
myPrivateMethod(bar);
}
};
})();
在这些例子中,模块中的作用域函数包裹在所有的函数周围,然后调用并立即存储返回值,这样有很多优点,包括:
下面的例子演示了全局变量(jQuery,Underscore)如何作为参数传递给模块的匿名函数。我们引入它们,并给它们取一个本地别名。
// 全局模块
var myModule = (function(jQ, _){
function privateMethod1(){
jQ(".container").html("test");
}
function provateMethod2(){
console.log(_.min([10, 5, 100, 2, 1000]}));
}
return {
publicMethod: function(){
privateMethod1();
}
};
// 引入jQuery和Uderscore
})(jQuery, _);
myModule.publicMethod();
下面的例子声明了一个全局变量,而不需要实现它们,并可以同样地作为全局变量引入到模块中。
// 全局模块
var myModule = (function(){
// 模块对象
var module = {},
// 私有属性
var privateVariable = "asd";
//私有方法
function provateMethod(){
// ...
}
module.publicProperty = "FooBar";
module.publicMethod = function(){
console.log(privateVariable);
}
return module;
})();
这里仅介绍jQuery下Module模式的实现,示例中定义了library函数,声明一个新库,并在创建新库时将init函数自动绑定到document.ready。
function library(module){
$(function(){
if(module.init()){
module.init();
}
});
return module;
}
var myLibrary = library(function(){
return {
init:function(){
// module implementation
// 模块实现
}
};
})();
首先,对于面向对象来说,比起真正的封装思想,从JavaScript的角度而言是很简洁的。 其次,它支持了私有数据
由于我们访问私有和公有成员的方法不同,当我们想改变可见性时,实际上我们要修改每一个使用过成员变量的地方。 此外,我们也无法访问那些在方法里添加的私有成员。 其他缺点包括: