非權威的JS模塊化編程筆記

前言:對於JS的模塊化編程,一直都處於邊學邊用的狀態,藉着這次重構代碼的機會,對「JS模塊化編程」作一個系統的完整的學習和整理。(隨時更新)javascript

參考文章:http://www.ruanyifeng.com/blo...html


什麼是模塊化編程?爲何須要模塊化編程?
當一個項目愈來愈大,那麼它包含的JS也會愈來愈多。過多的JS文件會下降代碼的可讀性,同時增長後續的開發和維護成本。容易出現一下情景:
「大神,爲何這個js在執行的時候會報錯?我命名包含進來了呀?」
「我看看...(5分鐘後),汗你這有問題。B.JS依賴於A.JS,因此引入時候要放在A.JS的後面,否則會報錯。」
爲了下降以上現象,引入模塊化編程思想,相似強類型語言的「類」、「模塊」。一個模塊(JS文件)完成一類功能,須要某功能時,引入其對應的模塊(JS文件)便可。java

如何進行模塊化編程?
模塊化是一個思想,當把「同一類」功能的方法(或函數)放到一塊兒,造成一個「類」,咱們就能夠把它們當成一個模塊:編程

function m1(){ //計算手續費...
//...
}
function m2(){ //計算收益...
//...
}

這樣,m1和m2就算是組成一個模塊了。可是,這樣的寫法「污染」了全局變量。好比,此時新來了一個同事C,他不知道m一、m2已經被前輩「佔」用了,而後本身寫了一個「模塊」,也包含了名爲m一、m2的方法。同事C在本身代碼裏引用以上模塊時,就會出現同名方法。爲了不以上問題,又對模塊化進行「升級」。服務器

模塊化編程造成
將模塊寫成對象,這樣即便重名了,由於方法屬於不一樣對象,因此不會形成衝突:異步

var module1 = new Object({
    _count : 0,
    m1 : function (){
            //...
        },
    m2 : function (){
            //...
        }
  });

這樣一來,同事C即便本身寫了一個模塊(對象),模塊(對象)裏包含同名方法也不須要擔憂衝突了模塊化

模塊化編程演變
有一天,技術大佬找到同事C,說他寫的模塊有問題,同事D在調用的時候發現BUG。同事C一臉懵逼的跑回座位上看着本身寫的模塊,內心泛着低估「本身命名都用了那麼久了,沒啥問題」。查看了一下同事D的代碼後,發現同事D不當心將他代碼裏邊的變量_count變成了空字符串:函數

module1._count=""

因此在使用其餘方法的時候才報錯,於找到同事D痛批了一頓...
後來回到座位上,同事C思考了,雖然只是不當心,可是萬一其餘人也不當心那可不行。因而,同事C想到了java裏邊的private變量,若是讓全部模塊都只暴露出方法,而不暴露屬性,這樣就能夠避免了這個問題的再次發生。學習

模塊化編程的雛形
經過「當即執行函數」,單獨將須要暴露出來的方法返回:ui

var module1 = (function(){
    var _count = 0;
    var m1 = function(){
        //...
        };
    var m2 = function(){
        //...
    };
    return {
    m1 : m1,
    m2 : m2
    };
    })();

模塊化編程的改造
同事C在開發的時候,引入了一個好久之前寫了模塊,他發現一個問題:若是要在原先寫好的模塊上新增功能,那麼就必需要改這個模塊,可是這麼一來就有可能影響到其餘使用這個模塊的項目。若是再準備一個新的模塊,而後把原來寫好的模塊複製出來,而後在這模塊上新增功能,這樣就出現重複代碼了。後來通過細心的斟酌,同事C改裝一下本身的模塊,增長模塊的擴展性:放大模式。

var module1 = (function (mod){
    mod.m3 = function () {
                //...
            };
    return mod;
})(module1);

模塊化的規範:AMD(異步模塊定義,Asynchronous Module Definition)
AMD規定,採用require()方法進行加載模塊。require()包含兩個參數:模塊、回調函數。

require([module], callback);

第一個參數:模塊,表示當前JS文件(也能夠是模塊)包含哪些模塊;
第二個參數:回調函數,當所需的模塊(第一個參數)被從服務器中下載並加載完成後進行調用。

AMD的實現待更新...

相關文章
相關標籤/搜索