JavaScript 模組化編程(筆記)

來源:互聯網
上載者:User

標籤:space   接收   main   特定   成功   網上   amd   用法   依賴性   

第一章 JavaScript模組化編程

(一):模組的寫法

一 原始寫法
// 模組就是實現特定功能的一組方法;只要把不同的函數(以及選項組的變數)簡單地放在一起,就算是一個模組;
    function m1(){
        // ...
    }
    function m2(){
        // ...
    }
// 上面的函數m1()和m2(),組成一個模組;使用時直接調用就行;
// 缺點:"汙染"了全域變數; 無法保證不與其他模組發生變數名衝突,而且模組成員之間看不出直接關係;

二 對象寫法

1234567891011121314 // 把模組寫成一個對象,所有的模組成員都放到這個對象裡面;  var module = new Object({    _count:0,    m1:function(){      // ...    },    m2:function(){      // ...    }  });// 上面的函數m1()和m2(),都封裝在module對象裡;使用時直接調用這個對象的屬性;  module.m1();// 但是,這樣的寫法會暴露所有模組成員,內部狀態可以被外部改寫;  module._count = 4;

三 立即執行函數寫法

12345678910111213141516   var module = (function(){    var _count = 0;    var m1 = function(){      // ...    };    var m2 = function(){     };    return {      m1:m1,      m2:m2    };  })();// 使用上面的寫法,外部代碼無法讀取內部的_count變數;  console.info(module._count); // undefined;// 上面的寫法就是JavaScript模組的基本寫法;

四 放大模式

12345678 // 如果模組很大,必須分成幾個部分,或者一個模組需要繼承另一個模組,這時就有必要採用"放大模式";  var module = (function(mod){    mod.m3 = function(){      // ...    };    return mod;  })(module);// 上面的代碼為module模組添加了一個新方法m3(),然後返回新的module模組;

五 寬放大模式

1234567 // 在瀏覽器環境中,模組的各個部分通常都是從網上擷取的,有時無法知道哪個部分會先載入;// 如果採用上一節的寫法,第一個執行的部分有可能載入一個不存在的Null 物件,這時就要採用"寬放大模式";  var module = (function(mod){    // ...    return mod;  })(window.module || {});// 與"放大模式"相比,"寬放大模式"就是"立即執行函數"的參數可以是Null 物件;

六 輸入全域變數

1234567 // 獨立性是模組的重要特點,模組內部最好不與程式的其他部分直接互動;// 為了在模組內部調用全域變數,必須顯式地將其他變數輸入模組;  var module = (function($,YAHOO){    // ...  })(jQuery,YAHOO);// 上面的module模組需要使用jQuery庫和YUI庫,就把這兩個庫(其實是兩個模組)當作參數輸入module;// 這樣做除了保證模組的獨立性,還使得模組之間的依賴關係變得明顯;

第二章 JavaScript模組化編程(二):AMD規範

一 模組的規範
// 目前,通行的JavaScript模組規範共有兩種:CommonJS和AMD;

二 CommonJS
// node.js將javascript語言用於伺服器端編程,這標誌"JavaScript模組化編程"正式誕生;
// node.js的模組系統,就是參照CommonJS規範實現的;
在CommonJS中,有一個全域性方法require(),用於載入模組;
    var math = require(‘math‘);        // 載入模組;
    math.add(2,3);                    // 調用模組方法=>5;

三 瀏覽器環境
// 上一節的代碼在瀏覽器中運行會有很大的問題;
    var math = require(‘math‘);
    math.add(2,3);
// 問題:必須在require(‘math‘)等math.js載入完成,才會執行math.add(2,3);
// 所以瀏覽器的模組,不能採用"同步載入",只能採用"非同步載入";==>AMD;

四 AMD
AMD(Asynchronous Module Definition)非同步模組定義;
// 採用非同步載入模組,模組的載入不影響它後面語句的運行,所有依賴這個模組的語句,都定義在一個回呼函數中,
// 等載入完成之後,這個回呼函數才會運行;
// AMD也採用require()語句載入模組,但是它要求兩個參數:
    require([module],callback);
// module:是一個數組,裡面的成員就是要載入的模組;
// callback:是載入成功之後的回呼函數;
    require([‘math‘],function(math){
        math.add(2,3);
    });
// math.add()與math模組載入不是同步的,瀏覽器不會發生假死;所以,AMD比較適合瀏覽器環境;

第三章 JavaScript模組化編程(三):require.js的用法
一 為什麼使用require.js
// 需要依次載入多個js檔案;
// 缺點:
// 1.載入的時候,瀏覽器會停止網頁渲染,負載檔案越多,網頁失去響應的時間就會越長;
// 2.由於js檔案之間存在依賴關係,因此必須嚴格保證載入順序,當依賴關係很複雜的時候,代碼的編寫和維護都會變得困難;
// 所以require.js解決了這兩個問題:
// 1.實現js檔案的非同步載入,避免網頁失去響應;
// 2.管理模組之間的依賴性,便於代碼的編寫和維護;

二 require.js的載入
1.載入require.js
    <script scr="js/require.js" defer async="true"></script>
// async屬性工作表明這個檔案需要非同步載入,避免網頁失去響應;IE不支援這個屬性,只支援defer,所以把defer也寫上;
2.載入main.js
    <script src="js/require.js" data-main="js/main"></script>
// data-main屬性的作用是,指定網頁程式的主模組=>main.js,這個檔案會第一個被require.js載入;
// 由於require.js預設的檔案尾碼名是js,所以可以把main.js簡寫成main;

三 主模組main.js的寫法
1.如果main.js不依賴任何其他模組,可以直接寫入JavaScript代碼;
// main.js
    alert(‘載入成功!‘);
2.如果main.js依賴於模組,這時就要使用AMD規範定義的require()函數;
// main.js
    require([‘moduleA‘,‘moduleB‘,‘moduleC‘],function(moduleA,moduleB,moduleC){
        // ...
    })
// require()函數接收兩個參數:
// 參數一:數組,表示所依賴的模組,即主模組依賴的三個模組;
// 參數二:回呼函數,當前面指定的模組都載入成功後,它將被調用;載入的模組會以參數形式傳入該函數,從而在回呼函數內部可以使用這些模組;
// require()非同步載入模組,瀏覽器不會失去響應;它指定的回呼函數,只有前面的模組都載入成功後,才會運行,解決了依賴性的問題;
執行個體:
    require([‘jquery‘,‘underscore‘,‘backbone‘],function($,_,Backbone){
        // ...
    });

四 模組的載入
// 使用require.config()方法,可以對模組的載入行為進行自訂;
// require.config()就寫在主模組(main.js)的頭部;
// 參數就是一個對象,這個對象的paths屬性指定各個模組的載入路徑;
// 設定以下三個模組的檔案預設和main.js在用一個目錄;
    require.config({
        paths:{
            "jquery":"jquery.min",
            "underscore":"underscore.min",
            "backbone":"backbone.min"
        }
    });

// 如果載入的模組和主模組不在同一個目錄,就要逐一指定路徑;
    require.config({
        paths:{
            "jquery":"lib/jquery.min",
            "underscore":"lib/underscore.min",
            "backbone":"lib/backbone.min"
        }
    });
// 或者直接改變基目錄(baseUrl)
    require.config({
        baseUrl:"js/lib",
        paths:{
            "jquery":"jquery.min",
            "underscore":"underscore.min",
            "backbone":"backbone.min"
        }
    });

// 如果模組在另一台主機上,也可以直接指定它的網址
    require.config({
        paths:{
            "jquery":"https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min"
        }
    });
// require.js要求,每個模組是一個單獨的js檔案;這樣的話,如果載入多個模組,就會發出多次HTTP請求,會影響網頁的載入速度;
// 因此,require.js提供了一個最佳化工具,當模組部署完畢以後,可以用這個工具將多個模組合并在一個檔案中,減少HTTP請求數;

五 AMD模組的寫法

// require.js載入的模組,採用AMD規範,也就是說,模組必須按照AMD的規定來寫;
// 具體來說,就是模組必須採用特定的define()函數來定義;如果一個模組不依賴其他模組,那麼可以直接定義在define()函數中;
// 在math.js中定義math模組
// math.js
    define(function(){
        var add = function(x,y){
            return x+y;
        };
        return {
            add:add
        };
    });
// 在main.js中載入math模組
    require([‘math‘],function(math){
        alert(math.add(1,1));
    });
// 如果這個模組還依賴其他模組,那麼define()函數的第一個參數,必須是一個數組,指明該模組的依賴性;
// math.js
    define([‘myLib‘],function(myLib){
        function foo(){
            myLib.doSomething();
        }
        return {
            foo:foo
        };
    });
// 當require()函數載入上面這個模組的時候,就會先載入myLib.js檔案;

六 載入非規範的模組

// 載入非規範的模組,在用require()載入之前,要先用require.config()方法,定義它們的一些特徵;
    require.config({
        shim:{
            ‘underscore‘:{
                exports:‘_‘
            },
            ‘backbone‘:{
                deps:[‘underscore‘,‘jquery‘],
                exports:‘Backbone‘
            }
        }
    });
// require.config()接收一個設定物件,這個對象除了有前面說過的paths屬性之外,還有一個shim屬性,專門用來配置不相容的模組;
// (1).定義deps數組,表明該模組的依賴性;
// (2).定義exports值(輸出的變數名),表明這個模組外部調用時的名稱;
比如:jQuery的外掛程式
    shim:{
        ‘jquery.scroll‘:{
            deps:[‘jquery‘],
            exports:‘jQuery.fn.scroll‘
        }
    };

七 require.js外掛程式

1.domready:可以讓回呼函數在頁面DOM結構載入完成之後運行;
    require([‘domready!‘],function(doc){
        // called once the DOM is ready;
    })    
2.text和image:允許require.js載入文本和圖片檔案;
    define([‘text!review.txt‘,‘image!cat.jpg‘],function(review,cat){
        console.log(review);
        document.body.appendChild(cat);
    });

JavaScript 模組化編程(筆記)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.