iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 21
0
自我挑戰組

你為什麼不問問神奇 JavaScript 呢?系列 第 21

Day21 - 運用閉包模組化

模組

標準模組可以這樣做

function CoolModule() {
    var something = "cool";
    var 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

這是Revealing Module ( 揭露模組 )的變體。

幹嘛用的呢?先來看程式碼。

  1. 先調用 CoolModule(),才會有模組實例 ( module instance )
  2. 會得到回傳的物件。
    有內層函數的參考,但沒內層變數的參考。(隱藏和私有化變數資料)
  3. assign 物件給 foo。
  4. 呼叫 foo 物件的方法,並執行。
  5. 這時候呼叫的 doSomething() 和 doAnother() 就會產生 closure。

要達成真正的模組化,需要兩個條件

  1. 必須有一個外層的包含函式 ( outer enclosing function ),而且必須要被調用一次。(建立新的模組實體)
  2. 函式至少回傳一個內層函式。 ( 藉由 closure 存取或修改私有狀態。)

另外,模組函式如果改成 IIFE,並將他串到函式展開式,
直接指定,可以得到單一實體。

var foo = (function CoolModule(){
    // some variable
    // some function
    // return literal object
})();
foo.doSomething(); // cool
foo.doAnother();   // 1 ! 2 ! 3

那也因為是模組函式,當然可以放入參數。( 這讓 Tony 漸漸覺得有做 Native 的感覺。)

function CoolModule(id) {
    function identify() {
        console.log( id );
    }
    return {
        identify: identify
    };
}
var foo1 = CoolModule( "foo 1" );
var foo2 = CoolModule( "foo 2" );

foo1.identify(); // "foo 1"
foo2.identify(); // "foo 2"

最後一個強大的功能,修改模組裡面的值。

var foo = (function CoolModule(id) {
    function change() {
        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

(這個範例要能夠不斷新增刪除的話,還有很長的路要走。)

現代模組

因為最重要的部分,有用到 .apply 這在後面章節的 this 才會再解釋。這部分就先略過了。

未來模組

還沒實現的模組化概念。還是先略過吧。這對 Tony 還是有點吃力。

參考資料

  1. 你所不知道的JS
  2. Revealing Module

上一篇
Day20 - 範疇與 Closure
下一篇
Day22 - 這些不是 this
系列文
你為什麼不問問神奇 JavaScript 呢?30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言