終於來到最後一節了!javascript
今天咱們會把咱們的種子模塊完成,以後就能夠開始擴展咱們的框架了!是否是開始有些興奮了呢?java
先來回顧一下以前的內容:jquery
咱們搞定了命名空間、多庫共存機制、模塊擴展機制。緩存
恩,跟咱們開始定好的目標只差一小步了。如今咱們來完成它框架
首先,先來用模塊擴展機制爲咱們的命名空間添加方法,咱們來簡單的添加三個方法:多庫共存、toString、toNumber函數
function(module, exports, require){ var _Cvm = window.Cvm , _$ = window.$; //在exports上面註冊方法,來爲命名空間擴展功能 exports.reName=function(deep){ //衝突處理機制 window.$ = _$; if(deep){ window.Cvm = _Cvm; }; return Cvm; }; exports.toString=function(val){ //toString return val.toString(); } exports.toNumber=function(str){ //toNumber var n = Number(str); return !isNaN(n) ? n : ""; } }
OK,那麼咱們定義好了一個模塊,以後在工廠方法中將模塊的方法返回給命名空間:測試
return (function(modules){// 用來註冊和生產用戶調用的模塊和方法,參數爲模塊的集合 var moduleDepot = {} //緩存區 function require(moduleId){ if(moduleDepot[moduleId]) return moduleDepot[moduleId]; //直接調用緩存 var module = { exports:{}, moduleId:moduleId, loaded:false }; modules[moduleId].call(module.exports, module, module.exports, require); //得到模塊 moduleDepot[moduleId] = module; //添加緩存 module.loaded=true; return module.exports //返回模塊 }; return require(0); // 返回第0個模塊
測試一下:ui
<script src="../jquery-1.8.3.min.js"></script> <script src="Cvm.js"></script> <script> //先引入一個命名空間一樣爲$的JQ var _ = $.reName(); var a = _.toString(123); var b = _.toNumber("456"); console.log(typeof a) //string console.log(typeof b) //number </script>
OK,到如今爲止,基本上咱們的種子模塊就完成了!this
只差一個問題:咱們只把第0個模塊註冊到了命名空間上,可是咱們不可能把全部功能都寫在同一個模塊裏,由於這樣的話就沒法多人去編寫框架了,並且對之後的維護升級都是一個巨大的屏障。spa
咱們須要一箇中介者來完善模塊的擴展機制:
function(module, exports, require){ var _ = require(1); //將擴展功能的模塊請求過來 var extend = _.extend; //得到擴展的方法 var p = {}; // 中介者 extend(p , require(2)); // 爲中介者註冊方法 module.exports = p; //最終返回中介者 }, //* 0-end *// // // //* 1-start *// function(module, exports){ // 擴展模塊 exports.extend = function(to , from){ var keys = Object.keys(from); var i = keys.length; while(i--){ to[keys[i]] = from[keys[i]]; } return to; } }, //* 1-end *// // // //* 2-start *// function(module, exports, require){ //多庫共存模塊 var _Cvm = window.Cvm , _$ = window.$; exports.reName=function(deep){ //多庫共存 window.$ = _$; if(deep){ window.Cvm = _Cvm; }; return Cvm; }; }, //* 2-end *//
使用中介者p來擴展功能,而後返回這個中介者。此時這個中介者已經擁有全部擴展後的功能了,因此即便咱們在種子模塊裏並無請求多庫共存的模塊,但由於它已經被擴展給了中介者,因此最後咱們仍是能夠獲得這個模塊的全部功能。
這樣,咱們的種子模塊就完全宣告完成了。你能夠在此基礎上,任意的擴展你的命名空間,也能夠很方便的完成模塊之間的依賴引用。
完整代碼:
!function(global , target){ if(typeof global !== 'undefined'){ global.Cvm = global.$ = target(); }else{ throw new Error("Cvm requires a window with a document") } }(typeof window !== 'undefined'? window : this , function(){ //工廠是一個函數 return (function(modules){// 用來註冊和生產用戶調用的模塊和方法,參數爲模塊的集合 var moduleDepot = {} //緩存區 function require(moduleId){ if(moduleDepot[moduleId]) return moduleDepot[moduleId].exports; //直接調用緩存 var module = { exports:{}, moduleId:moduleId, loaded:false }; modules[moduleId].call(module.exports, module, module.exports, require); //得到模塊 moduleDepot[moduleId] = module; //添加緩存 module.loaded=true; return module.exports //返回模塊 }; return require(0); })([ //* 0-start *// function(module, exports, require){ var _ = require(1); var extend = _.extend; var p = {}; // 中介者 extend(p , require(2)); module.exports = p; }, //* 0-end *// // // //* 1-start *// function(module, exports){ exports.extend = function(to , from){ var keys = Object.keys(from); var i = keys.length; while(i--){ to[keys[i]] = from[keys[i]]; } return to; } }, //* 1-end *// // // //* 2-start *// function(module, exports, require){ var _Cvm = window.Cvm , _$ = window.$; exports.reName=function(deep){ //多庫共存 window.$ = _$; if(deep){ window.Cvm = _Cvm; }; return Cvm; }; }, //* 2-end *// ]) })
最後說兩句:
模塊擴展機制的好處是:方便多人協做完成一個框架的編寫。
由於編寫一個大型、功能完備的框架畢竟不是一個容易的事情,須要不少人很長時間去完成的,因此模塊擴展機制的好處在此就有很大的發揮空間。
而模塊的編寫就像拼裝玩具,把各個獨立的功能拼接在一塊兒,就變成了一個完整而強大的功能。
實際上,編寫框架就是這樣一個過程:在工做中不斷積累業務需求與解決方法,而且不停的抽象你的代碼。當你的代碼累積到必定的數量級後,天然而然的就會開始編寫框架。
至於以後的功能,咱們之後再來展開!