深刻理解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

相关文章
相关标签/搜索