模塊化:將復雜的系統分解為高內聚、低耦合的模塊,使系統開發變得可控、可維護、可拓展,提高模塊的復用率。
異步模塊——AMD:請求發出后,繼續其他業務邏輯,知道模塊加載完城執行后續的邏輯,實現模塊開發中對模塊加載完成后的引用。
優點有很多,比如:
1:懶加載,提高網站性能
2:功能模塊化
3:解決命名沖突
4:...
參考require.js,那么我們來實現一個簡單的amd庫,主要有三個模塊方法
1.config——配置模塊路徑
2.define——定義模塊方法
3.require——模塊入口方法
以下是實現學習版的基本函數
;
(function(win) {
win.config = {}; //路徑配置
var cache = {}, //模塊緩存
require = function(deps, callback) {//模塊入口方法,deps,依賴模塊
count = 0, //未加載的模塊計數器
},
define = function(url, callback) {}, //定義模塊方法
loadModule = function(url, callback) {}, //模塊加載方法
loadDone = function(params, callback){},//所有模塊加載完畢
loadSript = function(url) {}; //加載js文件
win.require = require;
win.define = define;
})(window);
同時我們新建三個js文件,皆為同一個路徑,分別為demo.js,demo1.js,demo2.js
//demo1.js文件內容
define('demo1',function(){
return {
a: 1
}
})
//demo2.js文件內容
define('demo2',function(){
return {
b: 2
}
})
//demo.js
window.config = {
demo1: './demo1.js',
demo2: './demo2.js'
}
require(['demo1', 'demo2'], function(demo1, demo2) {
console.log(demo1)
console.log(demo2)
})
上面看起來很像是require.js的寫法吧!想必看了上面的代碼就知道這個代碼的意思,現在來讓我們實現它吧!
require = function(deps, callback) { //模塊入口方法
/*url:需要加載的文件,deps,依賴模塊*/
var i = 0,
params = [],
count = 0; //未加載的模塊計數器
for (; i < deps.length; i++) {
count++;
(function(index) { //閉包保存i值
loadModule(deps[index], function(module) {
count--
params[index] = module
if (count == 0) {//為0則所有模塊加載完畢
loadDone(params, callback)
}
})
})(i);
}
},
define = function(url, callback) { //定義模塊方法
cache[url].export = callback() //緩存
cache[url].onload(cache[url].export) //執行回調
},
loadModule = function(url, callback) { //模塊加載方法
if (!cache[url]) { //如果不存在模塊則加載並緩存
cache[url] = {
onload: callback,
export: null
};
loadSript(config[url])
} else {//否則直接從緩存中輸出
callback(cache[url].export)
}
},
loadDone = function(params, callback) { //所有模塊加載完畢
callback.apply(null, params)
},
loadSript = function(url) { //加載js文件
var script = document.createElement('script');
script.async = true;
script.type = 'text/javascript';
script.src = url
script.charset = 'UTF-8';
document.querySelector('body').appendChild(script)
};
<script src="requireDemo.js"></script>
<script src="demo.js"></script>
requireDemo.js就是我們寫的demo版本的amd的庫,運行demo.js,看看log出現什么
但是以上代碼還存在許多問題,如:
沒有處理參數,字符串
沒有處理循環依賴問題
沒有處理CMD寫法
沒有處理js文件加載狀態
define一個模塊顯示的聲明id,應該可以忽略顯示的聲明id,如define(function(){}),有興趣的同學可以參考司徒的文章getCurrentScript獲得當前js執行文件名稱
還有其他許多問題,但是對我們理解amd的基本原理是足夠了的,希望對同學們模塊化開發有幫助
