模块模式需要必备两个必要条件:
- 必须有外部的封装函数,该函数至少被调用一次(每次调用都会创建一个新的模块实例)。
- 封闭函数必须返回至少一个内部函数,这样内部函数才能在私有作用域中形成闭包,并且可以访问或者修改私有的状态。
//封装定义友好API
var MyModules = (function Manager(){
//将模块列表使用一个对象定义
var modules = {};
function define(name, deps, impl) {
for (var i=0; i<deps. length; i++) {
deps [i] = modules[deps[i]];
}
//代码核心,引入包装函数(可以是任何依赖),根据模块名称储存在对象中
modules[name] = impl.apply(impl, deps);
}
function get(name) {
//根据名称返回对应值
return modules[name];
}
return {
define: define,
get: get
}
})();
//使用MyModules.define定义模块:
MyModules.define("bar", [], function() {
function hello(who) {
return "Let me introduce:" + who;
}
return {
hello: hello
};
});
MyModules.define("foo", ["bar"], function (bar) {
var hungry = "hippo";
function awesome() {
console.log( bar.hello(hungry).toUpperCase );
}
return {
awesome: awesome
};
});
var bar = MyModules.get("bar");
var foo = MyModules.get("foo");
console.log(bar.hello("hippo")); // Let me introduce: hippo
foo.awesome(); // LET ME INTRODUCE: HIPPO
//“foo”和“bar”模块都是通过一个返回公共 API 的函数来定义的。
小结:模块就是模块,即使在它们外层加上一个友好的包装工具也不会发生任何变化。