ES6 模块

ES6 使用 exportimport 导出和导入模块。

导出模块

一个模块就是一个独立的 JS 文件,该文件内的变量外部无法获取。若希望能让外部获取模块内的变量,则要用 export 关键字暴露变量。

// 分别暴露(命名行内导出)export const age = 66export let name = 'Bruce'export function sayHello() {console.log('hello from m1.js')}
// 统一暴露(命名子句导出)let book = '红宝书'let price = 129let bookInfo = {author: 'Matt Frisbie',translator: '李松峰',}// 可以使用 as 关键字重命名,改名后原来的名字就不能用了export { book, price, bookInfo as bookMessage }
// 默认暴露(默认导出)export default {color: 'red',edition: 4,}

一个模块只能有一个默认导出,重复的默认导出会出错。

// SyntaxErrorconst obj = { age: 44 }export default objexport default {name: 'Modules'}

默认暴露和统一暴露可以组合到一起。

const foo = 'foo'const bar = 'bar'// foo 是默认暴露,bar 是统一暴露export { foo as default, bar }

本质上默认暴露是导出名为 default 的变量,导入的时候可以任意取名。因此后面不能跟变量声明语句。

// 等同export { foo as default }export default foo// 等同import xxx from 'module.js'import {default as xxx} from 'module.js'// 报错export default let a = 1

三种导出方式可以在同一个模块同时使用。

// 默认暴露export default {color: 'red',edition: 4,}// 统一暴露let bar = 666let foo = 'foo'export { bar, foo }// 分别暴露export let msg = 'good'

export 导出的是值的引用,导入值会随导出值的变化而改变,也就是通过接口可得到模块内部实时的值。

// m1.jsexport let name = 'Bruce'setTimeout(() => {name = 'good'}, 1000)import { name } from './m1.js'console.log(name) // 'Bruce'setTimeout(() => {console.log(name)}, 1500) // 'good'

导入模块

使用 import 关键字导入模块。

// 导入通过分别暴露和统一暴露导出的接口import { name, age, sayHello } from './m1.js'// 导入通过默认暴露导出的接口,变量名自取import defaultValue from './m3.js'// 混合导出的接口import defaultValue, { book, price, bookInfo } from './m3.js'

导入模块时可以对变量重命名。

import { bookInfo as bookMessage } from './m2.js'

可以使用 * 进行模块的整体导入,此时必须进行重命名。* 是一个对象,所有导入值都保存在这个对象上。

import * as person from './m1.js'console.log(person.name)console.log(person.age)person.sayHello()

import 命令会提升到模块顶部再执行,它是在编译阶段执行的,在代码运行之前。

由于它是静态执行,因此无法使用在运行时才能得到结果的结构。

// 不会报错,正常运行sayHello()import { sayHello } from './m1.js'// 报错import { 'say' + 'Hello' } from './m1.js'