模塊化的目的:
解決命名沖突
依賴管理
提高代碼可讀性
代碼解耦俱饿,提高復(fù)用性
立即執(zhí)行函數(shù):
從外部調(diào)用模塊的時候無法修改沒有暴露出來的變量、函數(shù)。
var myModule = (function(){
var var1 = 1;
var var2 = 2;
function fn1(){
}
function fn2(){
}
return {
fn1: fn1,
fn2: fn2
};
})();
CommonJS規(guī)范(NodeJS標(biāo)準(zhǔn),服務(wù)器端)
- 定義模塊 根據(jù)CommonJS規(guī)范,一個單獨的文件就是一個模塊。每一個模塊都是一個單獨的作用域处铛,也就是說,在該模塊內(nèi)部定義的變量拐揭,無法被其他模塊讀取撤蟆,除非定義為global對象的屬性
- 模塊輸出: 模塊只有一個出口,module.exports對象堂污,我們需要把模塊希望輸出的內(nèi)容放入該對象
- 加載模塊: 加載模塊使用require方法家肯,該方法讀取一個文件并執(zhí)行,返回文件內(nèi)部的module.exports對象
//模塊定義 myModel.js
var name = 'Byron';
function printName(){
console.log(name);
}
function printFullName(firstName){
console.log(firstName + name);
}
module.exports = {
printName: printName,
printFullName: printFullName
}
//加載模塊
var nameModule = require('./myModel.js');
nameModule.printName();
不同的實現(xiàn)對require時的路徑有不同要求盟猖,一般情況可以省略js拓展名息楔,可以使用相對路徑,也可以使用絕對路徑扒披,甚至可以省略路徑直接使用模塊名(前提是該模塊是系統(tǒng)內(nèi)置模塊)
AMD規(guī)范(異步模塊定義值依,RequireJS標(biāo)準(zhǔn),瀏覽器端)
requireJS主要解決兩個問題:
- require()函數(shù)在加載依賴的函數(shù)的時候是異步加載的,這樣瀏覽器不會失去響應(yīng)
- 它指定的回調(diào)函數(shù)碟案,只有前面的模塊都加載成功后愿险,才會運行,解決了依賴性的問題价说。
語法
定義模塊
define(id?, dependencies?, factory);
id:可選參數(shù)辆亏,用來定義模塊的標(biāo)識,如果沒有提供該參數(shù)鳖目,則為文 件名(去掉拓展名.js)
dependencies:是一個當(dāng)前模塊依賴的模塊名稱數(shù)組
factory:工廠方法扮叨,模塊初始化要執(zhí)行的函數(shù)或?qū)ο蟆H绻麨楹瘮?shù)领迈,它應(yīng)該只被執(zhí)行一次彻磁。如果是對象,此對象應(yīng)該為模塊的輸出值
加載模塊
require([dependencies], function(){});
第一個參數(shù)是一個數(shù)組狸捅,表示所依賴的模塊
第二個參數(shù)是一個回調(diào)函數(shù)衷蜓,當(dāng)前面指定的模塊都加載成功后,它將被調(diào)用尘喝。加載的模塊會以參數(shù)形式傳入該函數(shù)磁浇,從而在回調(diào)函數(shù)內(nèi)部就可以使用這些模塊
// 定義模塊 myModule.js
define(['dependency'], function(){
var name = 'Byron';
function printName(){
console.log(name);
}
return {
printName: printName
};
});
// 加載模塊
require(['myModule'], function (my){
my.printName(); });