javascript模块化(一)--总览

媒介:很久没写文章总结了,此次重要大略的总结一下 js中的模块化

1.模块

模块的职责:封装完成,暴露接口,声明依靠。先来一个对照,下面代码没有运用任何模块体系

(1)无封装

math.js:(1)没有封装性(2)接口不明显

    function add(a,b){
        return a+ b
    }
    function sub(a,b){
        return a - b
    }

caculator.js:(1)依靠math.js然则没有依靠声明 (2)运用全局状况

    var action = "add";
    function compute(a,b){
        switch (action){
            case "add": return add(a,b)
            case "sub": return add(a,b)
        }
    }

(2)字面量

math.js:(1)结构性好(2)接见掌握没有

    var math = {
        add:function add(a,b){
            return a+ b
        },
        sub:function sub(a,b){
            return a - b
        }
    }

caculator.js:(1)依靠math.js然则没有依靠声明 (2)没法标明属性是私有,无封装

    var caculator = {
        action:'add';
        compute:function compute(a,b){
            switch (action){
                case "add": return math.add(a,b)
                case "sub": return math.add(a,b)
            }
        }
    }

(3)IIFE:字值型的函数表达式

能够建立一个部份作用域,封装内部成员变量,经由历程return输出须要输出的接口

版本一:caculator-1.js:(1)完成了接见掌握(2)依旧没有依靠声明

    var caculator = (function(){
        var action = "add";
        return{
        compute:function compute(a,b){
            switch (action){
                case "add": return math.add(a,b)
                case "sub": return math.add(a,b)
            }
        }
    }
})()

版本二:caculator-2.js:(1)显现依靠声明(2)依然污染了全局变量(3)必需手动举行依靠治理
揭破模块情势:return部份与版本一不太一样,把要领定义在函数体内里,return的只是要领。详细可参考这位童鞋的文章:Javascript 设想情势 — Revealing Module(展现模块)情势

    var caculator = (function(m){
        var action = "add";
        function compute(a,b(){
            switch (action){
                case "add": return m.add(a,b)
                case "sub": return m.add(a,b)
            }
        }
        return{
            compute:compute
    }
})(math)

(4)定名空间

处置惩罚暴露全局变量的题目,只暴露一个相似namespace的全局变量就完成一切模块的声明

math.js:(1)第一个参数是模块声明;(2)第二个参数是声明依靠,现在是没有依靠的;(3)第三个参数是模块的组成

    namespace("math",[],function(){
        function add(a,b){
            return a+ b
        }
        function sub(a,b){
            return a - b
        }
        return{
            add:add,
            sub:sub
        }
    })

caculator.js:(1)有依靠性命(2)依靠math被当作参数传入

    namespace("caculator",["math"],function(m){
        var action = "add"
        function compute(a,b){
            return m[action](a,b)
        }
        return{
            compute:compute
        }
    })

namespace的代码:照样没有处置惩罚依靠治理的题目,假如各个模块疏散在差别的文件中,就要对剧本加载递次举行手动的排序

    var namespace = (function(){
        //缓存一切的模块
        var cache = {}
        function createModule(name,deps,definition){  //参数是:模块名,依靠列表,定义
            //先对参数举行推断,假如只要一个参数,就返回
            if(arguments.length === 1){
                return cache[name]
            }
            //必需获得一切依靠的模块,要保证前面的模块已被定义好了
            deps = deps.map(function(depName){
                return ns(depName)
            })
            //初始化模块并返回
            cache[name] = definition.apply(null,deps)
            return cache[name];
        }
        return createModule
    })()

2.模块体系

职责:(1)依靠治理:加载/剖析/注入/初始化 (2)决议模块的写法
下面总结三种典范的模块体系的写法

(1)commonjs

长处:

  1. 依靠治理成熟牢靠

  2. 社区活泼,范例接收度高

  3. 运行时支撑,模块定义异常简朴

  4. 文件级别的模块作用域断绝

  5. 能够处置惩罚轮回依靠

瑕玷:

  1. 不是规范构造的范例

  2. 同步的require,没有斟酌浏览器异步加载的历程

    然则照样有方法运用的,现在有许多东西能够把多个模块的文件打包成一个文件:browserify,webpack,component

看下面用commonjs写就的代码:
math.js:

    function add(a,b){
        return a+ b
    }
    function sub(a,b){
        return a - b
    }
    exports.add = add
    exports.sub = sub

caculator.js:

       var math = require("./math");  //依靠声明
        function Caculator(container){
            this.left = container.querySelector(".j-left" );
            this.right = container.querySelector(".j-right" );
            this.add = container.querySelector(".j-add" );
            this.result = container.querySelector(".j-result");
            
            this.add.addEventListener("click",this.compute.bind(this));
        }
        Caculator.prototype.compute = function(){
            this.result.textContent = math.add(+this.left.value, +this.right.value)
        }
        exports.Caculator = Caculator;  //暴露接口

用前端打包东西举行打包math.jscaculator.js
起首装置browserify,在敕令行输入敕令:browserify caculator.js > caculator-bundle.js
打包成形如定名空间的文件情势

(2)AMD

自然的作用于异步环境
AMD代码写法:
math.js:第一个参数是依靠列表

    define([],function(){
        function add(a,b){
            return a+ b
        }
        function sub(a,b){
            return a - b
        }
        return{  //接口暴露
            add:add,
            sub:sub
        }
    })

caculator.js:参数一是依靠声明,参数二是依靠注入

    define(["./math"],function(math){
    
        function Caculator(container){
                this.left = container.querySelector(".j-left" );
                this.right = container.querySelector(".j-right" );
                this.add = container.querySelector(".j-add" );
                this.result = container.querySelector(".j-result");
                
                this.add.addEventListener("click",this.compute.bind(this));
            }
            Caculator.prototype.compute = function(){}
            return{
                Caculator:Caculator
            }
        })

AMD还支撑一个叫Simplified CommonJS wrapping

    define(function(require,exports){
        var math = require("./math");
        function Caculator(container){
                this.left = container.querySelector(".j-left" );
                this.right = container.querySelector(".j-right" );
                this.add = container.querySelector(".j-add" );
                this.result = container.querySelector(".j-result");
                
                this.add.addEventListener("click",this.compute.bind(this));
            }
            Caculator.prototype.compute = function(){}
            exports.Caculator = Caculator;
        })

上述怎样猎取依靠列表呢?
函数经由历程toString能够打印出它的函数体,然后用正则表达式提取出来
factory.toString()
/require\(['"]([^'"]*)['"]\)/.exec(factory.toString())[1]

长处:

  1. 依靠治理成熟牢靠

  2. 社区活泼,范例接收度高

  3. 专为异步IO打造,合适浏览器环境

  4. 支撑相似Commonjs的誊写体式格局

  5. 经由历程插件api可支撑加载非js资本

  6. 成熟的打包构建东西,并可连系插件

瑕玷:

  1. 模块定义烦琐,须要分外嵌套

  2. 只是库级别的支撑,须要引入分外的库

  3. 没法处置惩罚轮回依靠

  4. 没法完成前提加载

(3)ES6/module

言语级别的支撑,将来的模块化

    原文作者:yangdepp
    原文地址: https://segmentfault.com/a/1190000005883330
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞