ECMAScript 6 的模块相比 CommonJS 的require (...)有什么优点?
关注者
388被浏览
39,9728 个回答
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。
延伸阅读: