您的位置:首页 > 产品设计 > UI/UE

3(phonegap源码分析)模块定义与请求(define require)

2013-08-09 19:11 411 查看
define和require是贯彻整个phonegap代码的核心函数,它们通过定义的一个匿名函数的即时调用来赋值的。事实上下面的匿名函数中省略了部分代码,当然省略的代码并不影响框架的主题功能,而是新版本中对原有功能的完善。

var  require,//myphonegap内部的工具函数,用来导入相关的模块
  define;//在myphonegap注册相关的模块

  //通过一个立即调用的匿名函数,来给require和define赋上实际的函数
  (function(){
var modules={};   // 模块数组,添加模块类似给这个对象添加了属性,模块名为属性名,模块对象为属性值,或者说是键值对

build = function(module){        //根据模块对象构造模块导出对象,模块导出对象存储在modules这个对象数组内
var factory = module.factory;
module.exports = {};           //给当前模块加入了一个exports属性
delete module.factory;		   //删除了module的属性
factory(require,module.exports,module);     //构建导出模块,module.exports是传出参数(实参,引用传递)
return module.exports;
}

require = function(id){            //根据模块名称/id请求模块对象,如果是第一次请求,就构建对象
if(!modules[id]){
throw "module " + id + " not found!";
}
return modules[id].factory?build(modules[id]):modules[id].exports;
}

define = function(id,factory){		 //定义模块,模块名称、构建模块对象的工厂方法。
if(modules[id]){
throw "module " + id + " is exist!";
}
modules[id] = {					//定义模块对象,左边的值为属性名,右边的值为传入的参数
id:id,
factory:factory
};
}
  })();


怎么来理解这部分代码呢?如果按其他面向对象语言(JAVA或C++)来理解,可以把这个匿名函数当做一个类,这个类对外提供两个外部方法,一个是require,一个是define,当然还有一个私有方法build,这个类的主要成员变量就是modules,好吧,modules,这个变量确实也没有其他地方直接使用它了。

modules是什么呢,modules字面意义是模型,那这个变量就是存储模块对象的。由前面得知,require和define的功能分别为请求和定义模块。但是并不是所有的模块在一开始就加载的,而模块也并不是每次请求都重新生成的。

所以modules就如同一个哈希表,主键就是模块名,比如”myphonegap”、”myphonegap/common”,值就是相应模块对象或模块对象的工厂函数。先通过define对这个哈希表添加一个主键模块名,和构建这个模块的工厂方法,此时是没有模块对象的;如果是第一次请求该模块,就会通过工厂函数来生成模块,生成模块之后对应的工厂方法会从表中删除,而如果已经请求过的模块就能在modules中找到对应模块对象。

现在来测试下,在myphonegap模块的工厂函数中添加一个打印输入语句,然后通过html加载这个js文件执行看结果。

  //注册myphonegap模块
    define("myphonegap", function(require, exports, module){
  		console.info("create myphonegap module");
          var myphonegap = {
  			Hello:function(name){
  				console.info("hello, "+name +" !");
  			}
  		};
  
  		module.exports = myphonegap;
    });
  
    //注册myphonegap/builder模块
    define("myphonegap/builder", function(require, exports, module){
  		console.info("create myphonegap/builder module");
  });


下面是HTML文件的源码,js文件放置在html文件同级的js文件夹内。之后的例子也会通过这种方式来执行,除非要用到android的交互功能了。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<script  type="text/javascript"  charset="utf-8"  src="js/myphonegap.js"></script>
</head>
<body>
<p>MYPHONEGAP  !</p>
</body>
</html>


运行结构如图,浏览器为chrome,下面显示的部分是它的“开发者工具”console下的内容



这里只执行了myphonegap模块工厂函数的代码,而myphonegap/builer的并没有执行,因为只有myphonegap模块被请求了。

window.myphonegap = require('myphonegap');
window.myphonegap.Hello("wen");


myphonegap.js 源码

;(function(){
  var  require,//myphonegap内部的工具函数,用来导入相关的模块   define;//在myphonegap注册相关的模块   //通过一个立即调用的匿名函数,来给require和define赋上实际的函数   (function(){ var modules={}; // 模块数组,添加模块类似给这个对象添加了属性,模块名为属性名,模块对象为属性值,或者说是键值对 build = function(module){ //根据模块对象构造模块导出对象,模块导出对象存储在modules这个对象数组内 var factory = module.factory; module.exports = {}; //给当前模块加入了一个exports属性 delete module.factory; //删除了module的属性 factory(require,module.exports,module); //构建导出模块,module.exports是传出参数(实参,引用传递) return module.exports; } require = function(id){ //根据模块名称/id请求模块对象,如果是第一次请求,就构建对象 if(!modules[id]){ throw "module " + id + " not found!"; } return modules[id].factory?build(modules[id]):modules[id].exports; } define = function(id,factory){ //定义模块,模块名称、构建模块对象的工厂方法。 if(modules[id]){ throw "module " + id + " is exist!"; } modules[id] = { //定义模块对象,左边的值为属性名,右边的值为传入的参数 id:id, factory:factory }; }   })();

  //注册myphonegap模块
  define("myphonegap", function(require, exports, module){
console.info("create myphonegap module");
var myphonegap = {
Hello:function(name){
console.info("hello, "+name +" !");
}
};

module.exports = myphonegap;
  });

  //注册myphonegap/builder模块
define("myphonegap/builder", function(require, exports, module) {

});

  define("myphonegap/channel",function(require,exports,module){
});

  //注册myphonegap/common模块
  //配置对象,将公共模块组织起来
define("myphonegap/common",function(require,exports,module){
});

 
define("myphonegap/exec", function(require, exports, module) {
});

  //注册myphonegap/platform模块
  define("myphonegap/platform", function(require, exports, module){
  });

  // 这里省略了其它插件的注册

  //注册myphonegap/utils模块
  define("myphonegap/utils", function(require, exports, module){
});

(function (context) {
}(window));
  //所有模块注册完之后,再导入myphonegap至全局环境中
  window.myphonegap = require('myphonegap'); window.myphonegap.Hello("wen");

})();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: