摘要: Javascript 设计模式学习之二 Module(模块)模式
Module模式是什么?
Module模式使用闭包封装私有状态和组织,只提供一个公有API,避免将其泄露至全局作用域,类似一个立即调用的函数表达式
Module模式有什么好处?
Module模式能够使单独的对象拥有公有/私有方法和属性,从而屏蔽来自全局作用域的影响,这样就可以使得函数名在页面上与其他脚本定义的函数冲突的可能性降低
Module模式怎么使用?
一个简单的例子:
let testModule = (function () {
let counter = 0;
return {
incrementCounter: () => {
return ++counter;
},
resetCounter:()=>{
console.log(`counter value prior to reset ${counter}`);
counter = 0;
}
}
}());
testModule.incrementCounter();
testModule.resetCounter();
testModule对象的私有属性counter只能通过公开的方法testModule.incrementCounter, testModule.resetCounter访问,testModule是一个全局变量
要点:
- 使用圆括号()将模块包起来,后面再加上一对圆括号,表示立即执行
- 闭包内需要公开的方法和变量,需要放在return{}里
- 在公开的方法内访问私有变量和方法
例子:购物车,模块本身是自包含在一个被称为basketModule的全局变量中
'use strict';
let basketModule = (function () {
// 私有
let basket = [];
function doSomethingPrivate() {
}
function doSomethingElsePrivate() {
}
// 返回一个暴露出的公有对象
return {
// 添加item到购物车
addItem: (values)=> {
basket.push(values);
},
// 获取购物车里item数
getItemCount: ()=> {
return basket.length;
},
// 私有函数的公有形式别名
doSomething:doSomethingPrivate,
// 获取购物车中所有item的价格总值
getTotal:function () {
let itemCount = this.getItemCount(), // 如果用arrow,this会出现undefined
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()); //2
console.log(basketModule.getTotal()); // 0.8
该模块中,已经返回了一个object,它会被自动赋值给basketModule
Module模式的缺点:
- 由于访问公有和私有成员的方式不同,当想改变成员的可见性时,需要修改每一个曾经使用过该成员的地方
- 无法为私有成员创建自动化单元测试
参考资料
《Javascript 设计模式》 【美】Addy and Osmani
© 著作权归作者所有