Module模式最初定义为一种在传统软件工程中为类提供私有和公有封装的方法,在JavaScript中,module模式能屏蔽全局变量,使函数名与页面上其他脚本定义的函数冲突的可能性降低,直接说就是为函数定义命名空间。
示例
计数器
创建一个自包含的模块来实现Module模式。
var testModule=(function(){
var counter=0;
return {
incrementCounter:function(){
return ++counter;
},
resetCounter:function(){
console.log("counter value prior to reset: "+counter);
counter=0;
}
}
})();// 匿名函数,实现后立即执行一次
// 增加计数器
console.log(testModule.incrementCounter());
// 检查计数器并重置
testModule.resetCounter();
输出结果:
________________________________________________________
对比另一种写法(闭包)
var otherModule=function(){
var counter=0;
return {
incrementCounter:function(){
return ++counter;
},
resetCounter:function(){
console.log("counter value prior to reset: "+counter);
counter=0;
}
}
};
// 创建计数器
var count=otherModule();
// 增加计数器
console.log(count.incrementCounter());
// 检查计数器并重置
count.resetCounter();
经典实现
一个包含私有变量,私有方法,公有变量,公有方法的Module模式。
var myNamespace=(function(){
// 私有计数器变量
var myPrivateVar=0,
//记录所有参数的私有方法
myPrivateMethod=function(foo){
console.log(foo);
};
return {
// 公有变量
myPublicVar:"foo",
//调用私有变量和方法的公有函数
myPublicFunction:function(bar){
//增加私有计数器值
myPrivateVar++;
//传入bar调用私有方法
myPrivateMethod(bar);
},
}
})();
购物车实例
var basketModule=(function(){
var basket=[];
function doSomethingPrivate () {
console.log("private function");
}
function doSomethingElsePrivate () {
console.log("else private function");
}
return{
addItem:function(values){
if(typeof(values)==="object"){
basket.push(values);
}else{
throw new Error("Must be Object");
}
},
getItemCount:function(){
return basket.length;
},
doSomething:doSomethingPrivate,
getTotal:function(){
var itemCount=this.getItemCount(),
total=0;
while(itemCount--){
total+=basket[itemCount].price;
}
return total;
}
}
})();
// 使用场景
basketModule.addItem({
item:"bread",
price:0.5
});
basketModule.addItem({
item:"butter",
price:0.3
});
console.log(basketModule.getItemCount());
console.log(basketModule.getTotal());
引入混入
因为Module是屏蔽全局变量,如果我们想在自己的模块中引入其它模块,比如Jquery,就要用到引入混入,将全局变量作为参数传递给模块的匿名函数,并取别名,实现如下
var myModuel=(function(JQ){
function privateMethod(){
JQ(".container").html("test");
}
return {
publicMethod:function(){
privateMethod();
}
}
})(jQuery);