历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。在 ES6 之前,社区制定了一些模块加载方案,最主要的有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。
export 命令
模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取模块内部的某个变量,就必须使用export关键字输出该变量。
下面是一个 JS 文件,里面使用export命令输出变量。
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
function multiply(x, y) { return x * y; };
export {firstName, lastName, year, multiply};
需要特别注意的是,export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系,不能直接导出一个值。在一个模块中,export可以调用多次。
import 命令
使用export命令定义了模块的对外接口以后,其他 JS 文件就可以通过import命令加载这个模块。
- 解构导入
import {firstName, lastName, year} from './profile';
- 重命名变量
import { lastName as surname } from './profile';
- 重复导入
import {name} from './module1';
import {age} from './module1';
- 模块的整体加载
import * as person from './module1'
export default 命令
使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法。为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。
export default function () {
console.log('foo');
}
其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。
import customName from './export-default';
customName(); // 'foo'
export default命令用于指定模块的默认输出。显然,一个模块只能有一个默认输出,因此export default命令只能使用一次。所以,import命令后面不用加大括号,因为只可能对应一个方法或者对象。
export 与 import 的复合写法
如果在一个模块之中,先输入后输出同一个模块,import语句可以与export语句写在一起。
export { foo, bar } from 'my_module';
// 等同于
import { foo, bar } from 'my_module';
export { foo, bar }; 。