zoukankan      html  css  js  c++  java
  • 模块化发展

    阶段1-文件划分

    将每个功能单独放在一个文件中,约定每一个文件是一个模块,当引用这个模块时,通过script标签引入到html页面中,直接使用模块中的方法或成员变量。

    // moduleA.js
    var name = 'moduleA';
    function say(){
        console.log('say i am'+name)
    }
    function write(){
        console.log('write i am'+name)
    }
    
    
    // moduleB.js
    var name = 'moduleB';
    function say(){
        console.log('say i am'+name)
    }
    function write(){
        console.log('write i am'+name)
    }
    
    // test.html
    <script src="moduleA.js"></script>
    <script src="moduleB.js"></script>
    <script>
    
    // 冲突
    say();
    
    // 变量可被修改
    name = 'test';
    </script>
    

    缺点:
    所有的变量全部暴露在全局中,都可以被随时访问和修改,随着文件的增多,很难通过约定避免命名冲突

    阶段2-命名空间

    // moduleC
    var moduleC = {
        name: 'moduleC',
        say: function(){
            console.log('say i am'+name)
        }
    }
    
    var moduleD = {
        name: 'moduleD',
        say: function(){
            console.log('say i am'+name)
        }
    }
    
    // test.html
    <script src="moduleA.js"></script>
    <script src="moduleB.js"></script>
    <script>
    moduleC.say();      // 正常调用
    
    moduleC.name = 'test';      // 模块中的成员变量可被随意修改
    
    </script>
    
    

    缺点:命名空间的方法极大程度的减小了命名冲突的可能,但是也存在成员变量可能被随意修改的风险

    阶段3-立即执行函数(IIFE)

    // moduleE
    var moduleE = (function(){
        var name = 'moduleE';
        function say(){
            console.log('say i am '+name)
        }
    
        return {
            say: say
        }
    })()
    
    
    // moduleF
    var moduleF = (function(){
        var name = 'moduleF';
        function say(){
            console.log('say i am '+name)
        }
    
        return {
            say: say
        }
    })()
    
    <script src="moduleE.js"></script>
    <script src="moduleF.js"></script>
    <script>
    
    moduleE.say();  // 正常调用
    moduleF.say();  // 正常调用
    console.log(moduleE.name)       //undefined
        
    </script> 
    

    实现了成员私有化,模块内的变量外界不能随意访问修改,通过立即执行函数也可以传递模块所需要的依赖,使得模块对外部的依赖更加清晰

    模块化规范

    CommonJS

    CommonJS规定每个文件都是一个模块,有独立的作用域。每个模块内部都有一个module对象代表当前模块,通过它来导出当前模块
    Commonjs的规范有以下特点:

    • 文件即模块,文件内所有代码都运行在独立的作用域,不会污染全局空间
    • 模块可以被多次引用。在第一次被加载时就会被缓存,之后都从缓存中读取
    • 加载某个模块就是引入该模块的module.exports属性
    • module.exports属性输出的是值的拷贝,一旦值被输出,模块内的变化不会影响到输出的值
    • 模块的加载顺序按照代码的引入顺序
    // m1.js
    module.exports = {
        name: 'm1',
        say: function(){
            console.log(this.name)
        }
    }
    
    //m2.js
    exports.test = function(){
        console.log('m2')
    }
    
    var m1 = require('./m1');
    var m2 = require('./m2');
    
    m1.say();   // m1
    m2.test();  // m2
    

    exports可以理解为module.exports的引用,可以给exports对象添加方法,但不能直接赋值。因为这样会切断exports与module.exports的联系。

    AMD

    由于Commonjs规范加载模块是同步的,不适合浏览器环境,所以出现了异步加载的模块化标准AMD,

    特点:同时并发加载所有依赖模块之后再执行当前模块的回调函数
    代表库:require.js
    require( [ ] ,function( ){ } )是require.js的核心之一,它接受两个参数。第一个参数是一个数组,表示所依赖的模块,第二个参数是一个回调函数,当前面指定的模块加载成功后,它将被调用。加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块

    require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC){
       ...
    });
    
    
    // 定义一个模块
    define(function(){
        var name = 'moduleJ';
        var sayHi = function(){
            console.log('i am require.js')
        }
        return {
            name: name,
            sayHi: sayHi
        };
    })
    
    // 引用模块
    require(['moduleJ'], function(){
            moduleJ.sayHi();
        })
    
    

    CMD

    CMD 规范整合了 CommonJS 和 AMD 规范的特点
    代表库: sea.js

    CMD 最大的特点就是懒加载,不需要在定义模块的时候声明依赖,可以在模块执行时动态加载依赖。当然还有一点不同,那就是 CMD 同时支持同步加载模块和异步加载模块。

    define(function(require, exports, module) {
      var add = require('math').add;
      exports.increment = function(val) {
        return add(val, 1);
      };
      module.id = "increment";
    });
    
    

    AMD 和 CMD 的两个主要区别

    • AMD需要异步加载模块,而CMD可以用同步的方式require依赖,也可以用require.async这种异步的方式
    • CMD遵循依赖就近原则,AMD遵循依赖前置原则。也就是说,在 AMD 中,我们需要把模块所需要的依赖都提前在依赖数组中声明。而在 CMD 中,我们只需要在具体代码逻辑内,使用依赖前,把依赖的模块 require 进来

    ES6模块化

    CommonJS和AMD都是在运行时确定依赖关系,即运行时加载,CommonJS加载的是拷贝,而ES6 module则是在编译时就确定依赖关系,所有加载的其实都是引用

    
    // 导出
    var first = 'test';
    var second = 'test';
    function func() {
        return true;
    }
    export {first, second, func};
    
    //引用
    import {first} from './a'
    
    • export default会导出默认输出,即用户不需要知道模块中输出的名字,在导入的时候为其指定任意名字。导入默认模块时不需要大括号,导出默认的变量或方法可以有名字,但是对外无效。export default只能使用一次。
  • 相关阅读:
    javascript教程系列-10.DOM(下)
    javascript教程系列-9.DOM(上)
    javascript教程系列-8.BOM
    javascript教程系列-7.Date对象
    javascript教程系列-6.String类型
    javascript教程系列-5.数组
    Python字符串、元组、列表、字典互相转换的方法
    python 中函数
    python中的字符串 列表 字典
    python 基础 知识
  • 原文地址:https://www.cnblogs.com/colagao/p/14490823.html
Copyright © 2011-2022 走看看