ECMAScript 6 的模块相比 CommonJS 的require (...)有什么优点?

感觉语法比 CommonJS 繁琐多了 http://es6.ruanyifeng.com/#docs/class
关注者
388
被浏览
39,972

8 个回答

ECMAScript 6 很多新功能都是毁誉参半,其中添加的一个新功能「模块 Module」也一样,有人认为 Module 可以帮助我们更好地写代码,也有人认为这增加了 Javascript 的复杂度,大多数人其实并不需要它。

到底是好是坏,这里不去辩别。但目前 Module 的语法已经定下来了,我们可以来探索下它。

ECMAScript 6 的模块有什么优点?

三个字:爽,快,强。

爽?

1. 语言层级支持,无需引入第三方库

2. 统一的 API,不用再写 [shim](

umdjs/umd · GitHub

)

3. 清爽的语法(与 Python 相似),功能却很丰富:

import:

import * as _ from 'src/lodash';           // 引入外部文件所有对象
import { each, map } from 'src/lodash';    // 引入外部文件部分对象
import _ from 'src/lodash';                // 引入外部文件默认导出对象
import _, { each, map } from 'src/lodash'; // 同时引入默认导出对象和部分对象
import 'src/lodash';                       // 只加载外部文件,但啥都不引入

export:

export let _ = function () {};           // 导出 _ 对象
export function lodash () {};            // 导出 lodash 函数
export default function (x) {return x};  // 导出匿名函数并设为默认导出对象
export { _, lodash as default };         // 一次导出多个对象

4. 由于可以选择性引入并重命名外部模块的部分对象,因此全局变量不被污染,局部变量也不怕被污染。

快?

1. 静态代码分析

基于目前第三方依赖管理工具的实现,我们要通过运行时检查当前模块引入了哪些外部模块,效率较低。但现在有了新语法的支持,我们就可以在运行前判断得出模块之间的依赖关系,进行代码检查。

2. 上一条已经很劲爆了有木有 :)

强?

1. 更好地支持循环依赖

循环依赖示例:

/* --- a.js --- */
import * as b from 'js/b';

// 在模块中间调用其它模块的方法
b.bar('b');

export function foo (from) {
  console.log('caller: ' + from);
}

/* --- b.js --- */
import * as a from 'js/a';

// 在模块中间调用其它模块的方法
a.foo('a');

export function bar (from) {
  a.foo(from);
}

/* --- main.js --- */
import {bar} from 'js/b';
bar('main');

结果:

caller: b         a.js:7
caller: a         a.js:7
caller: main      a.js:7

2. 提供模块加载器接口(Module Loader API)

有了这个接口后,模块的加载就有了更多的可能性,比如动态加载,加载后回调等。但我对于这个接口熟知不多,详见介绍:

The ECMAScript 6 module loader API

延伸阅读:

  1. harmony:modules [ES Wiki]
  2. ECMAScript 6 modules: the final syntax

只要不是最坏的标准,那就一定比没有标准强