模块是任何强大因工程需架构中不可或缺的一部分,它通常能够帮助我们清晰地分离和组织项目中的代码单元。
(1) 对象字面量
var myObject = { variableKey : ‘variableValue‘, functionkey : function () { // ... } };
对象字面量不需要用new运算符来进行实例化,但不能用在一个语句的开头,因为开始可能被解读为一个块的开始。在对象的外部,新成员可以使用如下赋值语句来添加到对象字面量上:
myObject.array = ‘arrayValue‘;
(2) Module(模块)模式
在JavaScript中,使用Module(模块)模式进一步模拟类的概念,通过这种方式,能够使一个单独的对象拥有公有/私有方法和变量,从而屏蔽来自全局作用域的特殊部分。产生的结果是:函数名与在页面上其他脚本定义的函数冲突的可能性降低。
1. 私有
Module模式使用闭包封装“私有”状态和组织。它提供了一种包装混合公有/私有方法和变量的方式,防止其泄露到全局作用域,并与其他开发人员的接口发生冲突。通过该模式,只需要返回一个公有API,而其他的一切则维持在私有闭包里面。
这为我们提供了一个屏蔽处理底层事件逻辑的整洁整体方案,同时暴露一个接口供应用程序的其他部分使用。该模式除了返回一个对象而不是一个函数之外,非常类似于立即调用的函数表达式。
应该说明的是,在JavaScript章没有真正意义上的“私有”。在Module模式内,由于闭包的存在,声明的变量和方法只在该模式内部可用。但在返回对象上定义的变量和方法,则可以外部使用者都可用。
2. 示例
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(); // 检查计数器的值并重置 testModule.resetCounter();
实际上,counter变量是完全与全局作用于隔离的,且这两个方法在其他地方也无法直接读取,表现的它像是一个私有变量,它的作用域被局限于模块的闭包之中。
下面是一个包含命名空间、公有和私有的Module模式:
var myNamespace = ( function () { var myPrivateVar = 0; var myPrivateMethod = function ( foo ) { console.log(foo); }; return { myPublicVar : ‘foo‘, myPublicFunc : function ( bar ) { myPrivateVar++; myPrivateMethod(bar); } }; } )();
我们来看另一个示例,一个使用这种模式实现的购物车:
var basketModule = ( function () { // 私有变量 var basket = []; // 私有方法 function doSomethingPrivate () { // ... } function doSomethingElsePrivate () { // ... } // 返回暴露出的公有对象 return { // 添加item到购物车 addItem : function ( values ) { basket.push ( values ); }, // 获取购物车的item数 getItemCount : function () { return basket.length; }, // 私有函数公有形式别名 doSomething : doSomethingPrivate, // 获取购物车里所有item的价格总值 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 : ‘apple‘, price : 0.3 }); console.log(basketModule.getItemCount()); // 2
(3) 总结
优点: 首先,相比真正封装的思想,他对于很多拥有面向对象背景的开发人员更加整洁,其次它支持私有数据,因此在Module模式中,代码的公有部分能够接触到私有部分,然而外界无法接触类的私有部分。
缺点: 由于我们访问公有成员和私有成员的方式不同,当我们想要改变可见性的时候,实际上我们必须要修改每一个曾经使用过该成员的地方。同样,我们也无法访问那些之后在方法里添加的私有成员。