// 第一种用法:export+声明语句
export let a = 1;
// 第二种用法:export+大括号
let b = 1;
export { // 这里的大括号不是对象
b
}
// 第三种用法:使用 as 重命名
let c = 1;
export { // 对外输出的是 cx,c 不再可见
c as cx
}
// 错
export 1;
// 错
let a = 1;
export a;
// 错
function b () {
}
export b;
接口与模块内部变量的绑定是动态的
export let a = 1;
setTimeout(() => {
a = 2;
}, 100); // 100毫秒后 a=2
2.import
import导入接口,大括号中的名称必须和导出的名称相同
// 可以使用 as 重命名,cx 不再可见
import {a, b, cx as cy} from './001';
可以用星号(*)指定一个对象,所有导出的接口都挂载到这个对象
import * as whole from './001';
也可以只执行不导入
import './001';
3.export default
export default指定默认导出接口,后面跟的是一个表达式,不能再是声明语句
let a = 1;
export default a;
// 此时函数是表达式,不是声明
export default function () {}
// 此时类是表达式,不是声明
export default class {}
import可以指定任意名字接收
// 001.mjs
// 一个模块只能有一个默认导出接口,也就是只能使用一次
let a = 1;
export default a;
export let b = 2;
// 002.mjs
// 接收默认导出的变量必须在最前面
import ax, * as x from './001';
console.log(ax, x, x.default); // 1 [Module] { b: 2, default: 1 } 1
根据以上输出,可以看出export default的本质
// export default
export default a;
// 等价于
export {a as default}
// 貌似可以在大括号中用 default 接收,但是因为 default 是关键字,可以用 as 重命名
import ax, {default as ay, b} from './001';
console.log(ax, ay, b); // 1 1 2
export与import的复合写法
// 001.mjs
const a = 1;
export default a;
export const b = 2;
// 002.mjs
// b并没有被导入到当前模块
export {b} from './001';
// 002.mjs
// 导出001.mjs中的默认接口
// 不能这样 export a from './001';
export {default} from './001';
// 002.mjs
// 重命名,此时 b 是默认导出接口,只能有一个默认接口
export {default as ax, b as default} from './001';
// 002.mjs
// 整体导出,不包括001.mjs中的默认接口
// 不能这样 import * as x from './001';
export * from './001';
循环加载
// a.mjs
import {b} from './b';
console.log('a.mjs');
console.log(b);
export let a = 'a';
// b.mjs
import {a} from './a';
console.log('b.mjs');
console.log(a);
export let b = 'b';
ES6 模块两个最主要的特点
相较于CommonJS,ES6 模块有两个最主要的特点。
1.静态加载
ES6 模块的最大特点就是静态加载,也就是在编译时确定模块之间的依赖关系以及导入和导出的接口(变量、函数、类),ES6 模块不能在运行时动态加载。
2.ES6 模块不是对象
ES6 模块不是对象,而是通过
export
导出接口,再通过import
导入。顶层的this
指向undefined
。export & import
1.export
export
的作用是导出接口(变量、函数、类)导出 函数 和 类 的用法也是这样。
不管是
export
还是import
都只能处于模块顶层,如果处于块级作用域内,会报错。import
在编译阶段生成只读引用,执行时,根据这个只读引用,到被加载的模块里面取值。接口与模块内部变量是一一对应关系,export
导出的是接口,不能是表达式。接口与模块内部变量的绑定是动态的
2.import
import
导入接口,大括号中的名称必须和导出的名称相同可以用星号(*)指定一个对象,所有导出的接口都挂载到这个对象
也可以只执行不导入
3.export default
export default
指定默认导出接口,后面跟的是一个表达式,不能再是声明语句import
可以指定任意名字接收根据以上输出,可以看出
export default
的本质export与import的复合写法
循环加载
执行 a.mjs ,根据多次调试,个人理解的执行过程如下(可能有偏差):
一、编译阶段
编译入口模块
编译阶段结束后,开始进行执行阶段。
二、执行阶段
import
语句参考
1.http://es6.ruanyifeng.com/#docs/module 2.http://es6.ruanyifeng.com/#docs/module-loader