先看源码:
1 // file: lib/scripts/require.js 2 var require,//导入函数,导入cordova库的内部已经注册的模块,第一次导入时,先创建模块 3 define; //注册函数,注册cordova的内部模块 4 5 // 通过一个立即调用的匿名函数,给require和define赋值 6 (function () { 7 var modules = {}; // 缓存所有的模块,初始化为一个空对象 8 9 function build(module) {//内部私有函数 10 var factory = module.factory; 11 module.exports = {}; 12 delete module.factory; // 第一次导入时根据模块提供的工厂构建,然后删除这个工厂,后续直接获取构建的结果 13 factory(require, module.exports, module); 14 return module.exports; 15 } 16 17 require = function (id) {//导入模块,若模块不存在,抛出异常 18 if (!modules[id]) { 19 throw "module " + id + " not found"; 20 } 21 return modules[id].factory ? build(modules[id]) : modules[id].exports; 22 }; 23 24 define = function (id, factory) {//定义模块,模块名称和构建模块的工厂方法 25 if (modules[id]) { 26 throw "module " + id + " already defined"; 27 } 28 modules[id] = { 29 id: id, 30 factory: factory 31 }; 32 }; 33 34 define.remove = function (id) {//移除模块 35 delete modules[id]; 36 }; 37 38 })();
1、首先在外部cordova环境中定义require和define两个变量,用来存储实现导入功能的函数和实现注册功能的函数。
2、然后用一个立即调用的匿名函数来实例化这两个变量,在这个匿名函数内部,缓存了所有的功能模块。
3、注册模块时,如果已经注册了,就直接抛出异常,防止无意中重定义,如确实需要重定义,可先调用define.remove。
4、从内部私有函数build中,可以看出,调用工厂函数时,提供了三个实参,require、module.exports、module,因此,在各个模块中定义的工厂函数,也相应的可以使用三个参数,最好就是如源代码中那样,使用三个命名参数来接受,当然,也可以直接使用arguments。