Skip to content

ES6模块对比CommonJS #2

Description

@gaoxianglyx

ES6模块的特点

  1. 总是处于严格模式
  2. 具有顶层 (top-level) 作用域,但又不是全局 (global) 作用域(import命令具有提升效果,不管写在哪一行都会提到模块头部首先执行)
  3. 可以通过 import 关键字从其他模块导入程序绑定 (bindings, 通常就是变量或者函数)
  4. 可以通过 export 关键字导出指定的 bingdings

严格模式(以下会报错)

  • with 语句
  • 函数重复命名的参数
  • 八进制数字直接量 (比如 010)
  • 重复属性名 ( ES5 会报错,ES6 不会)
  • 使用 implements, interface, let, package, private, protected, public, static 和 yield 作为标识符

ES6的模块的静态加载

  • 静态加载:在编译阶段进行加载(预编译)

JS是脚本语言,是边执行边编译的,这里的编译阶段应该是指的执行前的这个编译解释阶段

  • 动态加载:在运行时加载依赖

ES6模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。commonjs和AMD模块,都只能在运行时确定这些东西。

  • 运行时加载: CommonJS/AMD 模块就是对象;即在输入时是先加载整个模块,生成一个对象,然后再从这个对象上面读取方法,这种加载称为“运行时加载”
  • 编译时加载: ES6 模块不是对象,而是通过 export 命令显式指定输出的代码,输入时采用静态命令的形式。即在输入时可以指定加载某个输出值,而不是加载整个模块,这种加载称为“编译时加载

Commonjs和ES6模块的运行机制就像是深复制和浅复制

ES6模块的运行机制与CommonJS不一样,它遇到模块加载命令import时,不会去执行模块,而是只生成一个动态的只读引用。等到真的需要用到时,再到模块里面去取值,ES6模块是动态引用。

  • 在 CommonJS 中,导入(imports)是模块导出值的复制值(同时 require()动作是同步的)。也就是说,在一个模块中一个值和这个值导出被复制后的值不是同一个,两者之间不存在连接
  • 在 ES6 中,导入是对导出值的只读。因此,模块中的值和导出后的值是同一个,存在连接,只是在导入的模块中对这个值是只读的。“只读”说明在导入的模块中不能直接修改被导入的值,如果要修改被导入的值,可以通过调用被导入模块的函数来达到目的。

静态模块结构的优势:

  1. 在打包时消除死代码(dead code)。在项目开发的过程中,我们可以借助 ES6 实现模块化开发;在部署的时候,可以把这些分散的模块集中打包集成(打包减少了网络请求的数量,这点并不时很关键,因为在 HTTP/2 中将会有所改变;打包压缩了代码,减少了代码的体积;在打包过程中,没有用到的代码将会被移除)。
  2. 简洁高效的打包,不存在定制的打包格式(compact bundling, no custom bundle format)。ES6 模块可以被高效地合并,是因为所有的模块都被当作一个单独的作用域(single scope)(通过重命名变量来消除名冲突)。这些得益于 ES6 模块的两个特性:
  • 静态模块结构不存在模块的条件加载(但是仍可以通过把模块放到函数中来实现);
  • 导入对到导出的值只读,这意味着我们无需复制导出的值,而直接访问导出的值。
  1. 更快的导入检索(faster lookup of imports):
  • 在 CommonJS 中,通过复制来导入,同时模块存在动态机制(导出、导入),因而在查找属性的时候更加慢;
  • ES6 模块时静态的,意味着在模块执行之前就已经知道导入的值是什么,可以优化访问。
  1. 变量检查。同样得益于 ES6 的静态模块结构,我们可以在执行前进行导入、导出的变量检查。
  2. 为宏指令做准备(ready for macros)。macros 会是 JavaScript 发展蓝图中的一个 milestone。目前可以通过一些第三方的库来实现宏定义。
  3. 静态类型(static types)定义.
  4. 静态结构为支持其他编译型语言提供了可能。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions