JavaScript编程模式:模块的力量(1)
模块模式是一个常用的JavaScript编程模式。它很好理解,但是还有一些高级的使用方法没有引起广泛的注意。如果你已经非常了解模块模式,可以跳到"高级模式"的段落。
51CTO推荐阅读:JavaScript中的函数式编程实践
匿名闭包
匿名闭包是让一切成为可能的基础,而且这也是JavaScript最好的特性。我们创建个简单的匿名函数看看。函数内运行的代码都存在于闭包内,这个闭包在整个应用的生命周期内都保持私密和自己的状态。(相关阅读:揭开Javascript闭包的真实面目)
- (function () {
- // 所有的var和function都只存在于当前作用域内
- // 仍然可以读取到所有的全局变量
- }());
注意:包住匿名函数的"()"。这是JavaScript语言本身的要求,因为由function开头的代码一律被识别为"函数声明",用()包住则创建了一个函数表达式。
引用全局变量
JavaScript有个特质隐含的全局变量。无论一个name是否使用过,JavaScript解释器反向遍历作用域链查找这个name的var声明,如果没找到var,则这个对象是全局的。这意味着在一个匿名闭包中使用和创建全局变量很容易。不幸的是这让代码难与管理,对阅读代码的人来说很难区分哪些变量是全局的。幸好,我们的匿名函数提供了一个简单的替代方案。将全局变量作为参数传入匿名函数,这比用隐含全局变量更清晰更快速。例子:
- (function ($, YAHOO) {
- // 使用全局的 jquery 比如$ 和 YAHOO
- }(jQuery, YAHOO));
模块导出
当你不仅仅想使用全局变量,还想声明一些(全局变量)的时候。我们可以很方便地用匿名函数的返回值来导出(全局变量)。 这么做就是一个完整的模块模式基本形态。例子:
- var MODULE = (function () {
- var my = {},
- privateVariable = 1;
- function privateMethod() {
- // …
- }
- my.moduleProperty = 1;
- my.moduleMethod = function () {
- // …
- };
- return my;
- }());
我们声明了一个全局变量”MODULE”, 有两个公有属性: 分别是一个方法MODULE.moduleMethod和一个变量MODULE.moduleProperty。除此之外,它用匿名函数的闭包保持自己的私有内部状态。同时根据上一个例子,我们还可以很方便的引用全局变量。
高级模式
上面的内容对大多数用户已经很足够了,但我们还可以基于此模式发展出更强大,易于扩展的结构。
增生
模块模式的一个限制是整个模块必须写在一个文件里。在大型编码项目里工作的人都知道代码分成多个文件的重要性。幸好,我们又一个很好的解决方案。首先,我们导入模块,然后我们添加属性,然后我们再把它导出。例子:
- var MODULE = (function (my) {
- my.anotherMethod = function () {
- //添加一些方法
- };
- return my;
- }(MODULE));
为确保一致性我们再次使用var关键字,尽管这不是必须的。代码运行后,我们的模块会获得一个新的公有方法MODULE.anotherMethod。这个增生的文件也保持自己的私密性,内部状态和对他的导入。
松散增生
我们的上一个例子要求我们的初始化模块必须先运行。而增生必须第二步发生。这不应该是必要的。JavaScript的好处之一就是可以异步的读取脚本文件。我们可以创建灵活的多块的模块,用Loose Augmentation,他们可以按任何顺序加载自己。每个文件应该有如下的结构:
- var MODULE = (function (my) {
- // 添加一些功能
- return my;
- }(MODULE || {}));
在这个模式下,var声明总是必须的注意如果模块还不存在,导入就会新建模块。这意味着你可以使用类似LABJavaScript这样的工具并行的读取所有你的模块文件,没有任何的阻塞。
- 上一篇:DOM模型入门手册
- 下一篇:JavaScript DOM文档遍历实战(1)






