模块功能主要由
export和import构成。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。
export
export输出变量
// profile.js
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;
// 等价于(推荐)
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
export { firstName, lastName, year };
export输出函数
export function fn(x, y) {
return x * y;
}
- 使用
as对输出变量重命名
function v1() {}
function v2() {}
export {
v1 as streamV1,
v2 as streamV2,
v2 as streamLatestVersion // v2可以以不同的名字输出两次
}
- 另外,
export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。
export var foo = 'bar';
setTimeout(() => foo = 'baz', 500);
上面代码输出变量foo,值为bar,500 毫秒之后变成baz。
这一点与 CommonJS 规范完全不同。CommonJS 模块输出的是值的缓存,不存在动态更新,详见下文《Module 的加载实现》一节。
最后,export 命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错。这是因为处于条件代码块之中,就没法做静态优化了,违背了 ES6 模块的设计初衷。
import
import导入变量,通过as重命名输入的变量
// main.js
import { firstName, lastName, year } from './profile.js'
import { firstName as name } from './profile.js'
import输入的变量为只读的,若变量为对象,允许修改其属性
import {a} from './xxx.js'
a = {} // Syntax Error: 'a' is read-only
a.foo = 'hello' // 合法,成功改写,并且其他模块也可以读到改写后的值
import具有提升效果
foo()
import {foo} from 'my-module'
import会执行所加载模块
import 'lodash'
- 模块整体加载,即用星号(
*)指定一个对象,所有输出值都加载在这个对象上面。
// circle.js
export function area(radius) {
return Math.PI * radius * radius;
}
export function circumference(radius) {
return 2 * Math.PI * radius;
}
// main.js
import * as circle from './circle'
circle.area(2);
circle.circumference(2)
export default
- 为模块指定默认输出
export default function() {
console.log('我是default')
}
- 可以为输入指定任意名字
import customFn from './export-default.js'
customFn()