JavaScript進階【一】JavaScript模組化開發的基礎知識

向善的燈發表於2018-02-03
版權宣告:本文為博主原創文章,未經博主允許不得轉載。更多學習資料請訪問我愛科技論壇:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/79249047
//模組化的最初寫法
//1.最初寫法
//下面的m1m2就組成了一個模組
//缺點:"汙染"了全域性變數,無法保證不與其他模組發生變數名衝突,而且模組成員之間看不出直接關係。
function m1() {
    //---
}

function m2() {
    //---
}


//2.物件的寫法
//可以把模組寫成一個物件,所有的模組成員都放到這個物件裡面。
var module = new Object({
    _count: 0,

    m1 : function () {
        //---
        alert("函式1");
    },

    m2 : function () {
        //---
        alert("函式2");
    }
});

//物件方法模組的使用(開始呼叫模組裡面的成員)
//module.m1();
//module.m2();
//缺點:這樣的寫法會暴露所有模組成員,內部狀態可以被外部改寫
//module._count = 5;
//alert(module._count);


//3.立即執行函式的寫法
var module1 = (function () {
    var _count1 = 0;

    var m1 = function () {
        //----
    }
    var m2 = function () {
        //----
    }

    return {
        m1 : m1,
        m2 : m2
    }
})();

//使用上面的寫法,外部程式碼無法讀取內部的_count變數。
//alert(module1._count1);  //error


//4.放大模式
//給模組module1來新增一個新的方法m3(),然後返回新的module1模組
var module1 = (function (mod) {
    mod.m3 = function () {
        //---
    };

    return mod;
})(module1);


//5.寬放大模式
//"寬放大模式"就是"立即執行函式"的引數可以是空物件。
var module1 = (function (mod) {
    //---

    return mod;
})(window.module1 || {});


//6.輸入全域性變數
//獨立性是模組的重要特點,模組內部最好不與程式的其他部分直接互動
//為了在模組內部呼叫全域性變數,必須顯式地將其他變數輸入模組。
/*var module1 = (function ($, YAHOO) {
    //---
})(JQuery, YAHOO);
*/

//7.模組的規範
//有了模組,我們就可以更方便地使用別人的程式碼,想要什麼功能,就載入什麼模組。
//目前,通行的Javascript模組規範共有兩種:CommonJSAMD
//載入數學模組math.js
//這裡的require()用於載入模組
var math = require(`math`);
//呼叫模組提供的方法
var result = math.add(1, 2);
alert(result);

//瀏覽器端的模組,不能採用"同步載入"synchronous),只能採用"非同步載入"asynchronous)。
//上面的呼叫模組方式只能在math模組載入完畢之後,才能執行模組中的add方法


//10.AMD"非同步模組定義)
//第一個引數[module],是一個陣列,裡面的成員就是要載入的模組;第二個引數callback,則是載入成功之後的回撥函式。
//require([module], callback);

//math.add()math模組載入不是同步的,瀏覽器不會發生假死。所以很顯然,AMD比較適合瀏覽器環境。
//目前,主要有兩個Javascript庫實現了AMD規範:require.jscurl.jsrequire([`math`, function (math) {
    math.add(1, 2);
}]);



//----------------require.js的使用方法--------------------------

//最初的匯入.js檔案的寫法
/*
*  <script src="1.js"></script>
  <script src="2.js"></script>
  <script src="3.js"></script>
  <script src="4.js"></script>
  <script src="5.js"></script>
  <script src="6.js"></script>
*
* 【缺點】
* 1.載入的時候,瀏覽器會停止網頁渲染,載入檔案越多,網頁失去響應的時間就會越長
* 2.由於js檔案之間存在依賴關係,因此必須嚴格保證載入順序(比如上例的1.js要在2.js的前面),依賴性最大的模組一定要放到最後載入,當依賴關係很複雜的時候,程式碼的編寫和維護都會變得困難。
*
* require.js】解決的問題如下:
* 1)實現js檔案的非同步載入,避免網頁失去響應;
 (2)管理模組之間的依賴性,便於程式碼的編寫和維護。
* */

/**
 * require.js的具體使用方法如下:
 */


//使用require.js來進行模組化開發
//alert("main.js  載入完成!");

/*
* 真正常見的情況是,主模組依賴於其他模組,這時就要使用AMD規範定義的的require()函式。
* // main.js
  require([`moduleA`, `moduleB`, `moduleC`], function (moduleA, moduleB, moduleC){
    // some code here
  });
*
* 第一個引數是一個陣列,表示所依賴的模組,上例就是[`moduleA`, `moduleB`, `moduleC`],即主模組依賴這三個模組;
* 第二個引數是一個回撥函式,當前面指定的模組都載入成功後,它將被呼叫。
* []載入的模組會以引數形式傳入該函式,從而在回撥函式內部就可以使用這些模組
*
*
* require()非同步載入moduleAmoduleBmoduleC,瀏覽器不會失去響應;
* 它指定的回撥函式,只有前面的模組都載入成功後,才會執行,解決了依賴性的問題。
* 假定主模組依賴jqueryunderscorebackbone這三個模組,main.js就可以這樣寫
* require([`jquery`, `underscore`, `backbone`], function ($, _, Backbone){
    // some code here
  });
* require.js會先載入jQueryunderscorebackbone,然後再執行回撥函式。主模組的程式碼就寫在回撥函式中。
* */

//使用AMD規範定義的require()函式
//require.js假定這三個模組與main.js在同一個目錄,檔名分別為jquery.jsunderscore.jsbackbone.jsrequire([`jquery`, `underscore`, `backbone`], function ($, _, Backbone){
    // some code here
});



//模組的載入
//使用require.config()方法,我們可以對模組的載入行為進行自定義
require.config({
    //這裡指定了三個模組的檔名字以及檔案的路徑
    paths : {
        "jquery" : "lib/jquery.min",
        "underscore" : "lib/underscore.min",
        "backbone" : "lib/backbone.min"
    }
});

//也可以改變基目錄來實現
require.config({

    //指定基目錄
    baseUrl : "js/lib",

    //這裡指定了三個模組的檔名字以及檔案的路徑
    paths : {
        "jquery" : "jquery.min",
        "underscore" : "underscore.min",
        "backbone" : "backbone.min"
    }
});

//也可以使用目標伺服器中的地址來載入js檔案
//require.js要求, 每一個模組都是一個單獨的js 檔案
//當模組部署完畢以後,可以用這個require.js提供的工具將多個模組合併在一個檔案中,減少HTTP請求數
require.config({
    paths :{
        "jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min"
    }
});




//載入我自己定義的math.js 下面的模組的方法如下
require([`math`], function (math) {
    alert(math.add(1, 2));          //經過測試,也完美執行了
});

//在這裡去呼叫我的相減的模組
 require([`plus`], function (plus) {
     //這裡的意思是指去嗲用plus這個模組下面的result模組
     alert(plus.result(10, 5));     //5
 });


 //載入非規範的模組
//underscorebackbone這兩個庫,都沒有采用AMD規範編寫。如果要載入它們的話,必須先定義它們的特徵。
require.config({
    //shim屬性,專門用來配置不相容的模組
    shim : {
        `underscore`:{
            exports:`_`
        },

        //1exports值(輸出的變數名),表明這個模組外部呼叫時的名稱;
        //2deps陣列,表明該模組的依賴性。
        `backbone`:{
            deps:[`underscore`, `jquery`],
            exports:`Backbone`
        }
    }

});


//來配置一個JQuery外掛
require.config({
    shim : {
        `jquery.scroll`:{
            //這個模組的依賴項為jquery.js
            deps:[`jquery`],

            //這個模組外部呼叫的名稱就使用query.fn.scroll
            exports:`Jquery.fn.scroll`
        }
    }
});


//其他的require.js外掛
//domready外掛,可以讓回撥函式在頁面DOM結構載入完成後再執行。
require([`domready!`, function (doc) {
    //Dom 元素節點載入完畢之後再執行
}]);



//textimage外掛,則是允許require.js載入文字和圖片檔案。
define([
    `text!review.txt`,
    `image!cat,jpg`
],
    function (review, cat) {
        console.log(review);

        //把圖片檔案載入進來
        document.body.appendChild(cat);
    }
);

//這裡我定義了一個數學模組
//5.AMD模板的寫法
//模組必須採用特定的define()函式來定義。如果一個模組不依賴其他模組,那麼可以直接定義在define()函式之中。

//例項:有一個main.js檔案, 定義了一個math模組; math.js的寫法如下
/*define(function () {
    var add = function (x, y) {
        return x + y;
    }

    return {
        add: add
    };
});
*/



//如果這個模組還依賴其他模組的寫法如下
//require.js 在載入這個math.js模組的時候, 就會先載入plus.js 檔案
define([`plus`], function (plus) {

    var add = function (x, y) {
        alert("plus.js這個依賴項載入完畢!")
        return x + y;
    }

    return {
        add: add
    };
    
});

//我這裡又是一個模組
define(function () {
    alert("開始載入plus.js這個依賴項!");
    var minus = function (x, y) {
        return x - y;
    };

    return {
        result : minus
    }
});

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--async屬性表示這個檔案需要非同步載入; 避免網頁失去響應; IE不支援這個屬性,只支援defer,所以把defer也寫上-->
    <!--<script type="text/javascript" src="require2.3.5.js" defer async="true"></script>-->
    <!--<script type="text/javascript" src="main.js"></script>-->


    <!--載入require.js以後,下一步就要載入我們自己的程式碼;兩個寫在一塊的寫法如下
    data-main屬性的作用是,指定網頁程式的主模組; 也就是main.js 檔案,
    這個檔案會第一個被require.js載入。由於require.js預設的檔案字尾名是js    所以可以把main.js簡寫成main    -->
    <script src="require2.3.5.js" defer async="true" data-main="main"></script>

</head>
<body>

js 模組化開發測試
</body>
</html>


相關文章