深入理解JavaScript模組化程式設計:RequireJS
1、開篇的話
之前寫過一篇JavaScript模組化程式設計,當時是結合自己做的東西來寫的,比著葫蘆畫瓢。現在回過頭來看,依然有些不是太理解的地方,現在重新寫個小例子,加深自己的理解。JavaScript模組化概念及重要性以及RequireJS的好處就不介紹了,可以看文章末尾的連結,都有很詳細的闡述
2、定義模組(鍵值對)
模組定義使用define()方法,該方法有三個引數:
define(id?, dependencies?, function);
引數 | 說明 |
---|---|
id | 是一個string字串,它表示模組的標識(也就是模組的路徑,通過id才能知道從什麼位置去載入依賴的模組) |
dependencies | 是一個數組,成員是依賴模組的id |
function | 是一個回撥函式,在依賴的模組載入成功後,會執行這個回撥函式,它的引數是所有依賴模組的引用,如果回撥函式有返回值,會匯出出來 |
引數的預設可以參考文章3,有詳細的描述。在實際應用中,使用的更多的是匿名模組定義方式。
- 2.1、定義一個鍵值對,沒有任何依賴
user.js,程式碼如下:
define({
name:'bluce',
sex:'man',
age:25
})
- 2.2、定義一個函式,沒有任何依賴
color.js,程式碼如下。不知道這種是不是定義一個函式啊?
define(function () {
return {
black : "black",
red : "red"
}
});
2.1和2.2有什麼區別嗎?通過實際編碼,我覺得是一樣的。main.js中呼叫如下:
requirejs.config({
baseUrl:'js/app',
paths:{
user:'user',
color:'color'
}
});
requirejs(['user','color'],function(user,color){
alert(user.name);//bluce
alert(color.red);//red
});
debug顯示如下,可以看到user和color均是object,因此,在定義列舉型別時,這兩種方法是相同的。
3、定義模組(函式)
先來定義兩個模組,math.js與math_2.js,程式碼分別如下:
math.js:包含一個加法和乘法運算函式,注意,其返回的是物件(很重要)!!。
define(function(){
function add(x,y){
return x+y;
};
var multiply=function(x,y){
return x*y;
};
return {
add:add,
multiply:multiply
}
});
math_2.js:其只包含一個加法運算函式,注意,其返回的是函式!!
define(function(){
function add(x,y){
return x+y;
};
return add;
});
main.js中呼叫:
requirejs.config({
baseUrl:'js/app',
paths:{
math:'math',
math2:'math_2'
}
});
requirejs(['math','math2'],function(math,_add){
console.log(math);
console.log(_add);
alert(math.add(1,4)); //5
alert(math.multiply(4,4));//16
alert(_add(4,4));//8
});
console顯示如下:
這表明math是object,而add是函式。理解好這點,在後面的模組封裝中可以靈活利用這兩種方式。
require()函式(或requirejs(),一般簡寫為require())接受兩個引數。第一個引數是一個數組,表示所依賴的模組,上例就是[‘math’, ‘math2’, ],即主模組依賴這兩個模組;第二個引數是一個回撥函式,當前面指定的模組都載入成功後,它將被呼叫。載入的模組會以引數形式傳入該函式,從而在回撥函式內部就可以使用這些模組。
實際上,requirejs(['math','math2'],function(math,_add){}
與下面的程式碼達到的效果是一樣的。
//math
function add(x,y){//函式宣告
return x+y;
};
var multiply=function(x,y){ //函式表示式
return x*y;
};
var math={
add:add,
multiply:multiply
};
//math2
function add(x,y){
return x+y;
};
var _add = add;
這是因為JavaScript中object與function都是引用型別。
4、後續總結
1、定義模組時返回可以是object也可以是function。自己的迷惑主要是對JavaScript中物件的認識夠深刻,js中{}包圍的均可以看做是一個object,這樣在理解模組返回的是object還是function時就比較容易了。
2、目前還沒有使用非AMD模組,後續使用到了再來總結。