現在嵌入頁面里面的javascript代碼越來越復雜,於是可能依賴也越來越嚴重,使用別人開發的js也越來越多,於是在理想情況下,我們只需要實現核心的業務邏輯,其他都可以加載別人已經寫好的模塊。
於是js模塊化開發就顯的越來越重要了,但是,Javascript不是一種模塊化編程語言,它不支持"類"(class),更遑論"模塊"(module)了。(正在制定中的ECMAScript標准第六版,將正式支持"類"和"模塊",但還需要很長時間才能投入實用。)在現有的開發中,使用“模塊的效果”。於是我們簡單的總結了幾種模塊開發的方式。
(1)原始寫法:
模塊就是實現特定功能的一組方法。
只要把不同的函數(以及記錄狀態的變量)簡單地放在一起,就算是一個模塊。
function f1(){ } function f2(){ }
然后我們直接調用就可以了,但是這個做法有很多的弊端。例如:"污染"了全局變量,無法保證不與其他模塊發生變量名沖突,而且模塊成員之間看不出直接關系。
(2):使用對象的寫法
為了解決上面的缺點,可以把模塊寫成一個對象,所有的模塊成員都放到這個對象里面。這個寫法在我現在的項目中經常使用。
var func={ var count=0; inti:function(){ }, getValues:function(){ } }
然后我們要使用的話直接 func.inti() .但是這個方式有一個缺點:這樣的寫法會暴露所有模塊成員,內部狀態可以被外部改寫。func.count=1,這樣就很不安全。
(3):立即執行函數寫法
這個就可以防止修改內部的成員。
var func=({ var count=0; inti:function(){ }, getValues:function(){ } })():
func就是Javascript模塊的基本寫法。可以起到很好的保護私有成員的作用。
(4):放大模式
如果一個模塊很大,必須分成幾個部分,或者一個模塊需要繼承另一個模塊,這時就有必要采用"放大模式"
var func = (function (fn){ fn.m = function () { //... }; return fn; })(func)
上面的代碼為func模塊添加了一個新方法m(),然后返回新的func模塊。
(5):寬放大模式
在瀏覽器環境中,模塊的各個部分通常都是從網上獲取的,有時無法知道哪個部分會先加載。如果采用上一節的寫法,第一個執行的部分有可能加載一個不存在空對象,這時就要采用"寬放大模式"。
var func = ( function (fn){ //... return fun; })(window.func || {});
與"放大模式"相比,"寬放大模式"就是"立即執行函數"的參數可以是空對象。
(6):輸入全局變量
獨立性是模塊的重要特點,模塊內部最好不與程序的其他部分直接交互。為了在模塊內部調用全局變量,必須顯式地將其他變量輸入模塊。
var func = (function ($, baidu) { //... })(jQuery, baidu);
上面的func模塊需要使用jQuery庫和baidu庫,就把這兩個庫(其實是兩個模塊)當作參數輸入func。這樣做除了保證模塊的獨立性,還使得模塊之間的依賴關系變得明顯。
待續:js模塊加載器