Page 67 - 你不知道的JavaScript(上卷)
P. 67
var another = [1, 2, 3];
function doSomething() {
console.log( something );
}
function doAnother() {
console.log( another.join( " ! " ) );
}
return {
doSomething: doSomething,
doAnother: doAnother
};
}
var foo = CoolModule();
foo.doSomething(); // cool
foo.doAnother(); // 1 ! 2 ! 3
这个模式在 JavaScript 中被称为模块。最常见的实现模块模式的方法通常被称为模块暴露,
这里展示的是其变体。
我们仔细研究一下这些代码。
首先,CoolModule() 只是一个函数,必须要通过调用它来创建一个模块实例。如果不执行
外部函数,内部作用域和闭包都无法被创建。
其次,CoolModule() 返回一个用对象字面量语法 { key: value, ... } 来表示的对象。这
个返回的对象中含有对内部函数而不是内部数据变量的引用。我们保持内部数据变量是隐
藏且私有的状态。可以将这个对象类型的返回值看作本质上是模块的公共 API。
这个对象类型的返回值最终被赋值给外部的变量 foo,然后就可以通过它来访问 API 中的
属性方法,比如 foo.doSomething()。
从模块中返回一个实际的对象并不是必须的,也可以直接返回一个内部函
数。jQuery 就是一个很好的例子。jQuery 和 $ 标识符就是 jQuery 模块的公
共 API,但它们本身都是函数(由于函数也是对象,它们本身也可以拥有属
性)。
doSomething() 和 doAnother() 函 数 具 有 涵 盖 模 块 实 例 内 部 作 用 域 的 闭 包( 通 过 调 用
CoolModule() 实现)。当通过返回一个含有属性引用的对象的方式来将函数传递到词法作
用域外部时,我们已经创造了可以观察和实践闭包的条件。
如果要更简单的描述,模块模式需要具备两个必要条件。
52 | 第 5 章