ES6 export/import

163 阅读2分钟

模块功能主要由 exportimport 构成。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()