首頁  >  文章  >  web前端  >  詳解JavaScript模組化編程

詳解JavaScript模組化編程

高洛峰
高洛峰原創
2017-03-12 13:21:271420瀏覽

這篇文章詳解JavaScript模組化程式設計

第一章JavaScript模組化程式設計

(一):模組的寫法

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

物件寫法


// 把模块写成一个对象,所有的模块成员都放到这个对象里面;
  var module = new Object({
    _count:0,
    m1:function(){
      // ...
    },
    m2:function(){
      // ...
    }
  });
// 上面的函数m1()和m2(),都封装在module对象里;使用时直接调用这个对象的属性;
  module.m1();
// 但是,这样的写法会暴露所有模块成员,内部状态可以被外部改写;
  module._count = 4;


#三立即執行函數寫法


  var module = (function(){
    var _count = 0;
    var m1 = function(){
      // ...
    };
    var m2 = function(){

    };
    return {
      m1:m1,
      m2:m2
    };
  })();
// 使用上面的写法,外部代码无法读取内部的_count变量;
  console.info(module._count); // undefined;
// 上面的写法就是JavaScript模块的基本写法;


四放大模式


#

// 如果模块很大,必须分成几个部分,或者一个模块需要继承另一个模块,这时就有必要采用"放大模式";
  var module = (function(mod){
    mod.m3 = function(){
      // ...
    };
    return mod;
  })(module);
// 上面的代码为module模块添加了一个新方法m3(),然后返回新的module模块;


五寬放大模式


// 在浏览器环境中,模块的各个部分通常都是从网上获取的,有时无法知道哪个部分会先加载;
// 如果采用上一节的写法,第一个执行的部分有可能加载一个不存在的空对象,这时就要采用"宽放大模式";
  var module = (function(mod){
    // ...
    return mod;
  })(window.module || {});
// 与"放大模式"相比,"宽放大模式"就是"立即执行函数"的参数可以是空对象;


六輸入全域變數

##

// 独立性是模块的重要特点,模块内部最好不与程序的其他部分直接交互;
// 为了在模块内部调用全局变量,必须显式地将其他变量输入模块;
  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;
三節瀏覽器環境##//瀏覽器上在瀏覽器中執行的程式碼#/10311222-在瀏覽器中執行的代碼。會有很大的問題;
    var math = require('math');
    math.add(2,3);
// 問題:必須在require('math')等math. js載入完成,才會執行math.add(2,3);
// 所以瀏覽器的模組,不能採用"同步載入",只能採用"非同步載入";==>AMD;四AMD
AMD(Asyn
chr
onous 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###    98cb06b20f8457ecce5d74f566f6aa182cacc6d41bbb37262a98f745aa00fbf0###// async屬性表示這個檔案需要非同步載入,避免網頁失去回應;IE不支援這個屬性,只支援defer,所以把defer也寫上;###2 .載入###main###.js###    35be17e58c59207c30045b58673f385a2cacc6d41bbb37262a98f745aa00fbf0###// 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:{
          core.min ",
            "backbone":"backbone.min"
        }
    });

//


/已載入的模組和主模組未在指定的路徑和主模組中要逐不在其中一個目錄和主模組。
    require.config({
         require.config({
                   "backbone" :"lib/backbone.min"
        }
#    });
// 或直接改變基底目錄(baseUrl)
    require.config({#   
        paths:{
            "jquery":"jquery.min",
        "backbone":"backbone.min"
        }
    });

// 如果模組在另一台主機上,也可以直接指定它的網址
    require.config({

        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;
       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         foo:foo
        };
    }) ;
// 當require()函數載入上面這個模組的時候,就會先載入myLib.js檔;

六載入非規範的模組

// 載入非規範的模組,在用require()載入之前,要先用require.config()方法,定義它們的一些特徵;
    require.config({
       imim:{

   ##                exports:'_'

            },

         deps:['underscore','jquery'],

                exports:'Backbone'# }
    });
// require.config()接收一個配置物件,這個物件除了有前面說過的paths屬性之外,還有一個shim屬性,專門用來配置不相容的模組;
// (1).定義deps數組,表示該模組的依賴性;
// (2).定義exports值(輸出的變數名稱),表示這個模組外部呼叫時的名稱;
例如:jQuery的插件
    shim:{
        'jquery.scroll':{
           '
        }
    };

七require.js外掛程式
##1.domready:可以讓回呼函數在頁面DOM結構載入完成之後執行;
    require(['domready!'], function(doc){
        // called once the DOM is ready;
    })    
2.text與image:允許require.js. review.txt','image!cat.jpg'],function(review,cat){
        console.log(review);
       
document
.body.#       

doc ##    });

以上是詳解JavaScript模組化編程的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn