zoukankan      html  css  js  c++  java
  • javaScript模块化

    参考:https://blog.csdn.net/Real_Bird/article/details/54869066

    CommonJs(适用服务端)

    特点

    • 每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。
    • 在模块中使用global 定义全局变量,不需要导出,在别的文件中可以访问到。
    • 每个模块内部,module变量代表当前模块。这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。
    • 通过 require加载模块,读取并执行一个js文件,然后返回该模块的exports对象。
    • 所有代码都运行在模块作用域,不会污染全局作用域。
    • 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
    • 模块加载的顺序,按照其在代码中出现的顺序。

    加载与输出

          requiremodule.exportsrequire命令用于输入其他模块提供的功能,module.exports命令用于规范模块的对外接口,输出的是一个值的拷贝,输出之后就不能改变了,会缓存起来。加载完成后生成的对象如下

    {
      id: '...',
      exports: { ... },
      loaded: true,
      ...
    }

    id是模块名,exports是该模块导出的接口,loaded表示模块是否加载完毕。以后需要用到这个模块时,就会到exports属性上取值。即使再次执行require命令,也不会再次执行该模块,而是到缓存中取值。

    示例

    // math.js
    exports.add = function(a, b) {
      return a + b;
    }
    var math = require('math');
    math.add(2, 3); // 5

    优势

    CommonJS是同步加载模块,这对于服务器端不是一个问题,因为所有的模块都放在本地硬盘。等待模块时间就是硬盘读取文件时间,很小。但是,对于浏览器而言,它需要从服务器加载模块,涉及到网速,代理等原因,一旦等待时间过长,浏览器处于”假死”状态。所以在浏览器端,不适合于CommonJS规范

    ADM(适用浏览器)

    特点

    • 异步方式加载模块
    • 依赖前置(加载一个模块先加载依赖后执行模块和cmd的不同)

    加载与输出

    AMD也采用require命令加载模块,但是不同于CommonJS,它要求两个参数,其中回调函数中参数对应数组中的成员(模块)。

    //第一个参数是需要加载的模块数组,第二个是加载完成的回调函数
    require([module], callback);

    输出

    define(id?, dependencies?, factory);
    • id:模块的名字,如果没有提供该参数,模块的名字应该默认为模块加载器请求的指定脚本的名字;

    • dependencies:模块的依赖,已被模块定义的模块标识的数组字面量。依赖参数是可选的,如果忽略此参数,它应该默认为 ["require", "exports", "module"]。然而,如果工厂方法的长度属性小于3,加载器会选择以函数的长度属性指定的参数个数调用工厂方法。

    • factory:模块的工厂函数,模块初始化要执行的函数或对象。如果为函数,它应该只被执行一次。如果是对象,此对象应该为模块的输出值。

     示例

    输出这里只给出了参数三

    // math.js
    define(function() {
      var add = function(x, y) {
        return x + y;
      }
    
      return  {
        add: add
      }
    })
    // main.js
    require(['math'], function(math) {
      alert(math.add(1, 1));
    })

    如果math模块还依赖其他模块,写法如下

    // math.js
    define(['dependenceModule'], function(dependenceModule) {
      // ...
    })

    当require()函数加载math模块的时候,就会先加载dependenceModule模块。当有多个依赖时,就将所有的依赖都写在define()函数第一个参数数组中,所以说AMD是依赖前置的。

    CMD(AMD基础上优化依赖加载)

    特点

    • 依赖就近,延迟执行(在factory方法中灵活加载依赖)

    加载与输出

    与amd类似不同之处在于输出时

    define(factory)

    示例

    // CMD
    define(function(require, exports, module) {
      var a = require('./a');
      a.doSomething();
      var b = require('./b');
      b.doSomething();
    })

    对比amd没有了依赖参数并且在factory 方法执行时默认会传入三个参数:require、exports 和 module.

    UMD

    特点

    • 兼容各种加载规范

    示例

    (function (root, factory) {
    
        if (typeof define === 'function' && define.amd) {
    
            // AMD
    
            define(['jquery', 'underscore'], factory);
    
        } else if (typeof exports === 'object') {
    
            // Node, CommonJS之类的
    
            module.exports = factory(require('jquery'), require('underscore'));
    
        } else {
    
            // 浏览器全局变量(root 即 window)
    
            root.returnExports = factory(root.jQuery, root._);
    
        }
    
    }(this, function ($, _) {
    
        // 方法
    
        function a(){}; // 私有方法,因为它没被返回 (见下面)
    
        function b(){}; // 公共方法,因为被返回了
    
        function c(){}; // 公共方法,因为被返回了
    
    
    
        // 暴露公共方法
    
        return {
    
            b: b,
    
            c: c
    
        }
    
    }));

    ES6

    特点

    • 语法直观灵活对比adm和cmd

    加载与输出

    es6通过importexport实现模块的输入输出。其中import命令用于输入其他模块提供的功能,export命令用于规定模块的对外接口。

    输出

    var a = 1;
    var b = 2;
    var c = 3;
    //其中上面的as表示给导出的变量重命名
    export {a, b, c as d}

    要注意的是

    • export导出的变量只能位于文件的顶层,如果处于块级作用域内,会报错
    • export语句输出的值是动态绑定,绑定其所在的模块

    加载

    // abc.js
    var a = 1;
    var b = 2;
    var c = 3;
    export {a, b, c}
    
    //main.js
    //部分导入
    import {a, b, c} from './abc';
    //整体加载
    import * as adc from './abc'
    console.log(a, b, c);

    export default:在export输出内容时,如果同时输出多个变量,需要使用大括号{},同时导入也需要大括号。使用export defalut输出时,不需要大括号,而输入(import)export default输出的变量时,不需要大括号
    本质上,export default输出的是一个叫做default的变量或方法,输入这个default变量时不需要大括号

    // abc.js
    export {a as default};
    
    // main.js
    import a from './abc'; // 这样也是可以的
    
    // 这样也是可以的
    import {default as aa} from './abc';
    console.log(aa);
  • 相关阅读:
    父div的透明度不影响子div透明度
    vue-组件命名
    前端页面优化技巧
    Webstorm添加新建.vue文件功能并支持高亮vue语法和es6语法
    防止被坑
    vue安装教程总结
    vue找错
    前段进阶之路
    VM4061 layui.js:2 Layui hint: form is not a valid module
    三月十一号
  • 原文地址:https://www.cnblogs.com/cyh1282656849/p/13531094.html
Copyright © 2011-2022 走看看