Module Pattern 在 JavaScript 中十分普遍,JSer 在学习和工作中都会使用这种模式。
下面的代码中,会展示一些基础的 Module 用法。
1. 通过匿名函数闭包实现一个模块
var module = (function () {
// ...模块的具体实现
var module = {};
// private 成员
var _memeber = {};
// public 成员
module.member = {};
// 通过 return 语句返回模块
return module;
}());
2. 引入全局变量
可以通过给匿名函数传递参数引入全局变量
var module = (function (m1, m2) {
var module = {};
// 使用传入的全局变量参数
module.member = {
global1: m1,
global2: m2
};
return module;
}(global1, global2));
3. 在多个文件中定义模块
按照上述方式,目前只能在一个文件中定义模块,即模块的实现代码只能在一个闭包函数中执行。需要一种方式,可以使模块在多个文件中定义。我们可以借助匿名函数参数实现。将 module 作为参数传递到匿名函数中,然后扩展传入的模块。
module = (function (m) {
// 扩展模块
m.member2 = {};
return m;
}(module));
防止传入的 module 参数为 undefined
module = (function (m) {
m.member2 = {};
return m;
// 使用 || 操作符,保证传入的 module 不是 undefined
}(module || {}));
4. 多匿名函数定义同一个模块时,使用其他匿名函数中定义的模块成员
module = (function (m) {
// 存储 m.method
var old_method = m.method;
// 重新定义 m.method,还可以在新 method 中使用 old_method
m.method = function () {
//...
};
return m;
}(module));
5. 克隆和继承
var module2 = (function (p) {
var my = {};
// 注意这里不是deep copy,函数或者对象成员只是复制了引用
for (key in p) {
if (p.hasOwnProperty(key)) {
my[key] = old[key];
}
}
var p_method = p.method;
my.method = function () {
// override 方法,并且可以使用 p.method
}
return my;
}(module));
6. 私有成员跨文件共享
共享私有变量之前,可以调用 _unseal 方法,暴露私有成员,还可以调用 _seal 方法封闭私有成员。
var module = (function () {
var _private = my._private = my._private || {};
var _seal = my._seal = my._seal || function () {
delete my._private;
delete my._seal;
delete my._unseal;
};
var _unseal = my._unseal = my._unseal || function () {
my._private = _private;
my._seal = _seal;
my._unseal = _unseal;
};
}());