深刻理解javascript系列(十):模塊化與閉包

若是想在全部的地方都能訪問同一個變量,那麼應該怎麼辦呢?html

在實踐中這種場景不少,好比全局的狀態管理。jquery

但前面咱們介紹過,在實際開發中,不要輕易使用全局變量,那又該怎麼辦呢?模塊化的思惟可以幫助咱們解決這個問題。es6

模塊化開發是目前最流行,也是必需要掌握的一種開發思路。而模塊化實際上是創建在單例模式基礎之上的,所以模塊化開發和閉包息息相關。bash

目前流行的模塊化開發思路,不管是require,仍是ES6的modules,雖然實現方式不一樣,可是核心思路同樣。所以爲了方便你們理解模塊化的思惟,這裏就以創建在函數自執行基礎上的單例模式爲例,一塊兒來感覺一下模塊化開發的魅力。微信

第一,請記住:每個單例就是一個模塊。markdown

其實,你也知道,每個文件也是一個模塊。而這裏把每個單例模式假想成一個單獨的文件便可。定義一個模塊,而變量名就是模塊名。閉包

var module_test = (function() {
    
})();複製代碼

第二,每個模塊要想與其餘模塊交互,則必須有獲取其它模塊的能力,例如requirejs中的require與ES6modules中的import。app

//require
var $ = require('jquery');

//es6 modules
import $ from 'jquery';複製代碼

第三,每個模塊都應該有對外的接口,以保證與其餘模塊交互的能力。這裏直接使用return返回一個字面量對象的方式來對外提供接口。(你能夠回顧一下如今那些模塊的導出是多麼便捷)模塊化

var module_test = (function() {
      ...
      
      return {
          testfn1: function() {},
          testfn2: function() {}
      }  
})();複製代碼

如今咱們結合一個簡單的案例來走一遍模塊化開發的流程。這個例子想要實現的功能是每一個一秒,body的背景色就隨着一個數字的遞增在固定的三種顏色之間切換。函數

(1)首先建立一個專門用來管理全局狀態的模塊。這個模塊中有一個私有變量保存了全部的狀態值,並對外提供了訪問與設置這個私有變量的方法,代碼以下:

var module_status = (function() {
    var status = {
        number: 0,
        color: null
    }

    var get = function(prop) {
        return status[prop];
    }
    
    var set = function(prop,value) {
        status[prop] = value;
    }

    return {
        get,
        set
    }
})();複製代碼

(2)在來建立一個模塊,這個模塊專門負責body背景顏色的改變。

var module_color = (function() {
    
    //僞裝用這種方式執行第二步引入模塊
    //相似 import state from 'module_status';

    var state = module_status;
    var colors = ['yellow','#ccc','red'];

    function render() {
        var color = colors[state.get('number') % 3];
        document.body.style.backgroundColor = color;
    }

    return {
        render
    }
})();複製代碼

在這個模塊,引入了狀態管理的模塊,而且將顏色的管理與改變方式都定義在該模塊中,所以在使用時咱們只需調用render方法就能夠了。

接下來咱們還須要建立另一個模塊來負責顯示當前的number的值,用於參考對比。

var module_context = (function() {
    var state = module_status;

    function renderNumber() {
        document.body.innerHTML = 'now number is' + state.get('number');
    }

    return {
        renderNumber
    }
})()複製代碼

這些功能模塊都建立完畢後,最後咱們只需建立一個主模塊便可。這個主模塊的目的就是藉助功能模塊,來實現咱們想要的效果。

var module_main = (function() {
    var state = module_status;
    var color = module_color;
    var context = module_context;

    setInterval(function() {
        var newNumber = state.get('number') + 1;
        state.set('number',newNumber);

        color.render();
        context.renderNumber();
    },1000)
})();複製代碼

好了,整一個模塊化就完成了。你能夠將整段代碼插入到一個HTML文件script標籤下便可看到展現效果。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>change yourself</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
<script>
    var module_status = (function() {
        var status = {
            number: 0,
            color: null
        }

        var get = function(prop) {
            return status[prop];
        }

        var set = function(prop,value) {
            status[prop] = value;
        }

        return {
            get,
            set
        }
    })();

    var module_color = (function() {

        //僞裝用這種方式執行第二步引入模塊
        //相似 import state from 'module_status';

        var state = module_status;
        var colors = ['yellow','#ccc','red'];

        function render() {
            var color = colors[state.get('number') % 3];
            document.body.style.backgroundColor = color;
        }

        return {
            render
        }
    })();

    var module_context = (function() {
        var state = module_status;

        function renderNumber() {
            document.body.innerHTML = 'now number is' + state.get('number');
        }

        return {
            renderNumber
        }
    })();

    var module_main = (function() {
        var state = module_status;
        var color = module_color;
        var context = module_context;

        setInterval(function() {
            var newNumber = state.get('number') + 1;
            state.set('number',newNumber);

            color.render();
            context.renderNumber();
        },1000)
    })();
</script>複製代碼

運行以上完整代碼,就能夠看到若是效果啦


固然它是每一個一秒變一次的....

這些都是我以往的學習筆記。若是您看到此筆記,但願您能指出個人錯誤。有這麼一個羣,裏面的小夥伴互相監督,堅持天天輸出本身的學習心得,不輸出就出局。但願您能加入,咱們一塊兒終身學習。歡迎添加個人我的微信號:Pan1005919589

相關文章
相關標籤/搜索