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