AMD規範及require.js用法(Javascript模塊化編程)
網頁越來(lái)越像桌面程序,需要(yào / yāo)一(yī / yì /yí)個(gè)團隊分工協作、進度管理、單元測試等等......開發者不(bù)得不(bù)使用軟件工程的(de)方法,管理網頁的(de)業務邏輯。Javascript模塊化編程,已經成爲(wéi / wèi)一(yī / yì /yí)個(gè)迫切的(de)需求。理想情況下,開發者隻需要(yào / yāo)實現核心的(de)業務邏輯,其他(tā)都可以(yǐ)加載别人(rén)已經寫好的(de)模塊。Javascript社區做了(le/liǎo)很多努力,在(zài)現有的(de)運行環境中,實現"模塊"的(de)效果。本文總結了(le/liǎo)當前"Javascript模塊化編程"的(de)最佳實踐,說(shuō)明如何投入實用。雖然這(zhè)不(bù)是(shì)初級教程,但是(shì)隻要(yào / yāo)稍稍了(le/liǎo)解Javascript的(de)基本語法,就(jiù)能看懂。
一(yī / yì /yí)、原始寫法
模塊就(jiù)是(shì)實現特定功能的(de)一(yī / yì /yí)組方法。
隻要(yào / yāo)把不(bù)同的(de)函數(以(yǐ)及記錄狀态的(de)變量)簡單地(dì / de)放在(zài)一(yī / yì /yí)起,就(jiù)算是(shì)一(yī / yì /yí)個(gè)模塊。
function m1(){
//...
}
function m2(){
//...
}
上(shàng)面的(de)函數m1()和(hé / huò)m2(),組成一(yī / yì /yí)個(gè)模塊。使用的(de)時(shí)候,直接調用就(jiù)行了(le/liǎo)。
這(zhè)種做法的(de)缺點很明顯:"污染"了(le/liǎo)全局變量,無法保證不(bù)與其他(tā)模塊發生變量名沖突,而(ér)且模塊成員之(zhī)間看不(bù)出(chū)直接關系。
二、對象寫法
爲(wéi / wèi)了(le/liǎo)解決上(shàng)面的(de)缺點,可以(yǐ)把模塊寫成一(yī / yì /yí)個(gè)對象,所有的(de)模塊成員都放到(dào)這(zhè)個(gè)對象裏面。
var module1 = new Object({
_count : 0,
m1 : function (){
//...
},
m2 : function (){
//...
}
});
上(shàng)面的(de)函數m1()和(hé / huò)m2(),都封裝在(zài)module1對象裏。使用的(de)時(shí)候,就(jiù)是(shì)調用這(zhè)個(gè)對象的(de)屬性。
module1.m1();
但是(shì),這(zhè)樣的(de)寫法會暴露所有模塊成員,内部狀态可以(yǐ)被外部改寫。比如,外部代碼可以(yǐ)直接改變内部計數器的(de)值。
module1._count = 5;
三、立即執行函數寫法
使用"立即執行函數"(Immediately-Invoked Function Expression,IIFE),可以(yǐ)達到(dào)不(bù)暴露私有成員的(de)目的(de)。
var module1 = (function(){
var _count = 0;
var m1 = function(){
//...
};
var m2 = function(){
//...
};
return {
m1 : m1,
m2 : m2
};
})();
使用上(shàng)面的(de)寫法,外部代碼無法讀取内部的(de)_count變量。
console.info(module1._count); //undefined
module1就(jiù)是(shì)Javascript模塊的(de)基本寫法。下面,再對這(zhè)種寫法進行加工。