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

        definerequire是贯彻整个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
			};
		}
  })();

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

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

        所以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");
	
})();




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值