JavaScript 模塊

模塊

【示例】:

function CoolModule() {
    var something = "cool",
        another = [1, 2, 3];
        
    function doSomething() {
        console.log(something);
    }
    
    function doAnother() {
        console.log(another.join(" ! "));
    }
    
    return {
        doSomething: doSomething,
        doAnother: doAnother
    };
}

var foo = CoolModule();

foo.doSomething(); // cool
foo.doAnother(); // 1 ! 2 ! 3

【解釋】:

  • 這個(gè)模式在 JavaScript 中被稱為模塊。最常見的實(shí)現(xiàn)模塊模式的方法通常被稱為模塊暴露,這里展示的是其變體。
  • 首先,CoolModule() 只是一個(gè)函數(shù),必須要通過調(diào)用它來創(chuàng)建一個(gè)模塊實(shí)例。如果不執(zhí)行外部函數(shù),內(nèi)部作用域和閉包都無法被創(chuàng)建。
  • 其次,CoolModule() 返回一個(gè)用對(duì)象字面量語法 { key: value, ... } 來表示的對(duì)象。這個(gè)返回的對(duì)象中含有對(duì)內(nèi)部函數(shù)而不是內(nèi)部數(shù)據(jù)變量的引用。我們保持內(nèi)部數(shù)據(jù)變量是隱藏且私有的狀態(tài)??梢詫⑦@個(gè)對(duì)象類型的返回值看作本質(zhì)上模塊的公共 API。
  • 這個(gè)對(duì)象類型的返回值最終被賦值給外部的變量 foo,然后就可以通過它來訪問 API 中的屬性方法。

【注意】:從模塊中返回一個(gè)實(shí)際的對(duì)象并不是必須的,也可以直接返回一個(gè)內(nèi)部函數(shù),例如 jQuery(jQuery 和 $ 標(biāo)識(shí)符就是 jQuery 模塊的公共 API,但它們本身都是函數(shù))。

【模塊模式需要具備的兩個(gè)必要條件】:

  1. 必須有外部的封閉函數(shù),該函數(shù)必須至少被調(diào)用一次。
  2. 封閉函數(shù)必須返回至少一個(gè)內(nèi)部函數(shù),這樣內(nèi)部函數(shù)才能在私有作用域中形成閉包,并且可以訪問或者修改私有的狀態(tài)。

【注意】:一個(gè)具有函數(shù)屬性的對(duì)象本身并不是真正的模塊。換言之,一個(gè)從函數(shù)調(diào)用所返回的,只有數(shù)據(jù)屬性而沒有閉包函數(shù)的對(duì)象并不是真正的模塊。

【示例】:改進(jìn)-單例模式

var foo = (function CoolModule() {
    var something = "cool",
        another = [1, 2, 3];
        
    function doSomething() {
        console.log(something);
    }
    
    function doAnother() {
        console.log(another.join(" ! "));
    }
    
    return {
        doSomething: doSomething,
        doAnother: doAnother
    };
})();

foo.doSomething(); // cool
foo.doAnother(); // 1 ! 2 ! 3

【解釋】:將模塊函數(shù)轉(zhuǎn)換成了 IIFE,立即調(diào)用這個(gè)函數(shù)并將返回值直接賦值給單例的模塊實(shí)例標(biāo)識(shí)符 foo。

【提示】:模塊也是普通的函數(shù),因此也可以接受參數(shù)。

【用法】:命名將要作為公共 API 返回的對(duì)象。

var foo = (function CoolModule(id) {
    function change() {
        // 修改公共 API
        publicAPI.identify = identify2;
    }
    
    function identify1() {
        console.log(id);
    }
    
    function identify2() {
        console.log(id.toUpperCase());
    }
    
    var publicAPI = {
        change: change,
        identify: identify1
    };
    
    return publicAPI;
})("foo module");

foo.identify(); // foo module
foo.change();
foo.identify(); //FOO MODULE

【解釋】:通過在模塊實(shí)例的內(nèi)部保留對(duì)公共 API 對(duì)象的內(nèi)部引用,可以從內(nèi)部對(duì)模塊實(shí)例進(jìn)行修改,包括添加或刪除方法和屬性,以及修改它們的值。

現(xiàn)代的模塊機(jī)制

大多數(shù)模塊依賴加載器/管理器本質(zhì)上都是將這種模塊定義封裝進(jìn)一個(gè)友好的 API。

【示例】:

var MyModules = (function Manager() {
    var modules = {};
    
    function define(name, deps, impl) {
        for(var i = 0; i < deps.length; i++) {
            deps[i] = modules[deps[i]];
        }
        modules[name] = impl.apply(impl, deps);
    }
    
    function get(name) {
        return modules[name];
    }
    
    return {
        define: define,
        get: get
    };
})();

MyModules.define("bar", [], function() {
    function hello(who) {
        return "Let me introduce: " + who;
    }
    
    return {
        hello: hello
    };
});

MyModules.defind("foo", ["bar"], function(bar) {
    var hungry = "hippo";
    
    function awesome() {
        console.log(bar.hello(hungry).toUpperCase());
    }
    
    return {
        awesome: awesome
    };
});

var bar = MyModules.get("bar");
var foo = MyModules.get("foo");

console.log(bar.hello("hippo"));
foo.awesome();

未來的模塊機(jī)制

ES6 中為模塊增加了一級(jí)語法支持。在通過模塊系統(tǒng)進(jìn)行加載時(shí),ES6 會(huì)將文件當(dāng)作獨(dú)立的模塊來處理。每個(gè)模塊都可以導(dǎo)入其他模塊或特定的 API 成員,同樣也可以導(dǎo)出自己的 API 成員。

詳細(xì)內(nèi)容請(qǐng)參考 ES6 模塊機(jī)制。

小結(jié)

  • 模塊有兩個(gè)主要特征:(1)為創(chuàng)建內(nèi)部作用域而調(diào)用了一個(gè)包裝函數(shù);(2)包裝函數(shù)的返回值必須至少包括一個(gè)對(duì)內(nèi)部函數(shù)的引用,這樣就會(huì)創(chuàng)建涵蓋整個(gè)包裝函數(shù)內(nèi)部作用域的閉包。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ## 前言 The Module Pattern,模塊模式,也譯為模組模式,是一種通用的對(duì)代碼進(jìn)行模塊化組織與定義...
    b2e16cc43137閱讀 3,158評(píng)論 1 4
  • 原文鏈接:http://www.cnblogs.com/lvdabao/p/js-modules-develop....
    舌尖上的大胖閱讀 839評(píng)論 0 1
  • 參考資料 Modules/1.0——維基百科CommonJS Modules/1.0——伯樂在線js模塊化——博客...
    BeYanJin閱讀 3,244評(píng)論 0 5
  • 模塊通常是指編程語言所提供的代碼組織機(jī)制,利用此機(jī)制可將程序拆解為獨(dú)立且通用的代碼單元。所謂模塊化主要是解決代碼分...
    MapleLeafFall閱讀 1,251評(píng)論 0 0
  • 2018級(jí)中一(1)班由42名學(xué)生組成,所有學(xué)生都是運(yùn)動(dòng)訓(xùn)練專業(yè)的,分屬不同的訓(xùn)練隊(duì),有不同的專項(xiàng)教練。其中...
    天狼隊(duì)海蓉閱讀 2,414評(píng)論 0 1

友情鏈接更多精彩內(nèi)容