zoukankan      html  css  js  c++  java
  • 对于模块加载:ES6、CommonJS、AMD、CMD的区别

    运行和编译的概念

    编译包括编译和链接两步。

    编译,把源代码翻译成机器能识别的代码或者某个中间状态的语言。

    比如java只有JVM识别的字节码,C#中只有CLR能识别的MSIL。还简单的作一些比如检查有没有粗心写错啥关键字了啊.有啥词法分析,语法分析之类的过程。

    链接,是把编译生成的二进制文件,组合成为一个系统可以执行的可执行文件。

    运行:

    把编译出来的可执行文件代码在系统中执行的过程,此时被装载到内存中

    (代码保存在磁盘上没装入内存之前是个死家伙.只有跑到内存中才变成活的).

    运行时类型检查就与前面讲的编译时类型检查(或者静态类型检查)不一样.不是简单的扫描代码.而是在内存中做些操作,做些判断.

    模块的加载

    ES6、CommonJS、AMD、CMD指的都是一种规范。

    CommonJS

    为在浏览器环境之外构建JavaScript生态系统而产生的项目,比如服务器和桌面环境中。

    一个单独的文件就是一个模块,代码都运行在模块作用域,如果想在多个文件分享变量,必须定义为global对象的属性。(不推荐)

    //模块内部,module变量代表当前模块,它的exports属性是对外的接口
    //其他文件加载该模块,实际上就是读取module.exports变量。
    var x = 5;
    var addX = function (value) {
      return value + x;
    };
    module.exports.x = x;
    module.exports.addX = addX;
    //PS:不能直接对module.exports赋值,只能给它添加方法或者属性

    加载机制:

    模块可多次加载,但模块的运行只在第一次加载时,运行结果被缓存了,以后再加载,就直接读取缓存结果。

    通过require()同步加载依赖,导出API输出到当前模块,多个模块不能并行加载。

    输入的是值的拷贝。也就是说,一旦输出一个值,模块内部的变化就影响不到这个值

    应用:

    服务器端的Node.js遵循CommonJS规范,Node.js主要用于服务器的编程,加载的模块文件一般都已经存在本地硬盘,所以加载起来比较快,不用考虑异步加载的方式,所以CommonJS规范比较适用。

    如果是浏览器环境,要从服务器加载模块,这是就必须采用异步模式。所以就有了 AMD 、CMD 的解决方案,AMD与CMD都借鉴了CommonJs

    AMD 、CMD

    AMD(Asynchronous Module Definition)异步模块加载,AMD 里,require 分全局 require 和局部 require。

    CMD(Common Module Definition) 通用模块加载,提供模块定义及按需执行模块。CMD 里,没有全局 require,而是根据模块系统的完备性,提供 seajs.use 来实现模块系统的加载启动

    优劣:

    AMD | 速度快 | 会浪费资源 | 预先加载所有的依赖,直到使用的时候才执行
    CMD | 只有真正需要才加载依赖 | 性能较差 | 直到使用的时候才定义依赖

    AMD:

    define(['./a', './b'], function(a, b) { //运行至此,a.js和b.js文件已下载完成 a模块和b模块已执行完,直接可用;
        a.doing();
        // 此处省略500行代码
        b.doing();
    });

    CMD:

    define(function(require, exports, module) {
         var a = require("./a"); //等待a.js下载、执行完
         a.doing();
         // 此处省略500行代码
         var b = require("./b"); //依赖就近书写
         b.doing();
    });

     ES6

    使用export或export default导出,import导入。

    import是编译时调用,所以不能使用表达式和变量,这些只有在运行时才能得到结果的语法结构。

    import是解构过程,本质是输入接口,不允许在加载模块的脚本里面,改写接口。

    import命令具有提升效果,会提升到整个模块的头部,首先执行。

    import语句会执行所加载的模块,因此可以有下面的写法。

    import 'lodash';

    上面代码仅仅执行lodash模块,但是不输入任何值。

    多次重复执行同一句import语句,那么只会执行一次。

    在一个模块之中,先输入后输出同一个模块,export和import语句可以结合在一起,写成一行:

    export { foo, bar } from 'my_module';
    
    // 可以简单理解为
    import { foo, bar } from 'my_module';
    export { foo, bar };

    注意的是,foobar实际上并没有被导入当前模块,只是相当于对外转发了这两个接口,导致当前模块不能直接使用foobar

    export与export default的区别:

    1.export与export default均可用于导出常量、函数、文件、模块等
    2.在一个文件或模块中,export、import可以有多个,export default仅有一个
    3.通过export方式导出,在导入时要加{ },export default则不需要

    4. 

    (1)模块输出单个值,使用export default

    (2) 模块输出输出多个值,使用export

    (3) export default与普通的export不要同时使用

    //a.js  export
    export const str = "blablabla~";
    export function log(sth) { 
      return sth;
    }
    
    //b.js  import
    import { str, log } from 'a'; //也可以分开写两次,导入的时候带花括号
    
    
    //a.js  export default
    const str = "blablabla~";
    export default str;
    
    
    //b.js  import
    import str from 'a'; //导入的时候没有花括号
    
    //本质上,a.js文件的export default输出一个叫做default的变量,然后系统允许你为它取任意名字。所以可以为import的模块起任何变量名,且不需要用大括号包含

    import和require的区别

    vue模块引入使用import,node模块引入使用require

    遵循规范

    • require 是 AMD规范引入方式
    • import是es6的一个语法标准,如果要兼容浏览器的话必须转化成es5的语法(最好去看文档

    加载

    • require是运行时调用在运行时确定模块的依赖关系,得到模块对象及输入/输出的变量,无法进行静态优化。所以require的是运行的结果,把结果赋值给某个变量。
      1. 通过require引入基础数据类型时,属于复制该变量。
      2. 通过require引入复杂数据类型时,数据浅拷贝该对象。
    • import是编译时调用,支持编译时静态分析,不需要的方法就不会加载,便于JS引入宏和类型检验,不能包含运行才知道结果的表达式等

    写法

    require / exports :

    const fs = require('fs')
    exports.fs = fs
    module.exports = fs

    import / export:

    import fs from 'fs'
    import {default as fs} from 'fs'
    import * as fs from 'fs'
    import {readFile} from 'fs'
    import {readFile as read} from 'fs'
    import fs, {readFile} from 'fs'
    
    export default fs
    export const fs
    export function readFile
    export {readFile, read}
    export * from 'fs'
  • 相关阅读:
    有限元矩形单元一阶拉格朗日插值函数流程
    有限元二阶拉格朗日插值函数理论
    MATLAB有限元二维编程(三角单元)
    【项目管理】项目经理每天、每周、每月应该做的都在这
    【项目管理】中小公司PMO不一样期间的责任
    【项目管理】PRINCE2常见问答
    如何用几句话概括PRINCE2学习?
    项目管理——收益管理
    【项目管理】项目管理发展的新阶段——PRINCE2项目管理方法
    【MSP是什么】最佳管理实践指南
  • 原文地址:https://www.cnblogs.com/yaoyao-sun/p/10815196.html
Copyright © 2011-2022 走看看