# 模块化

# export写法

export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系

// 报错
export 1;

// 报错
var m = 1;
export m;

报错,因为没有提供对外的接口。第二种写法通过变量m,还是直接输出 1。1只是一个值,不是接口。正确的写法是下面这样。

// 写法一
export var m = 1;

// 写法二
var m = 1;
export {m};

// 写法三
var n = 1;
export {n as m};

同样的,function和class的输出,也必须遵守这样的写法。

# export default写法

正是因为export default命令其实只是输出一个叫做default的变量,所以它后面不能跟变量声明语句。

// 正确
export var a = 1;

// 正确
var a = 1;
export default a;

// 错误
export default var a = 1;

上面代码中,export default a的含义是将变量a的值赋给变量default。所以,最后一种写法会报错。 同样地,因为export default命令的本质是将后面的值,赋给default变量,所以可以直接将一个值写在export default之后。

// 正确
export default 42;

// 报错
export 42;

上面代码中,后一句报错是因为没有指定对外的接口,而前一句指定对外接口为default。

export 与 import 的复合写法

export { foo, bar } from 'my_module';


// 可以简单理解为
import { foo, bar } from 'my_module';
export { foo, bar };

上面代码中,export和import语句可以结合在一起,写成一行。但需要注意的是,写成一行以后,foo和bar实际上并没有被导入当前模块,只是相当于对外转发了这两个接口,导致当前模块不能直接使用foo和bar。

注意

  1. ES6模块之中,顶层的this关键字返回undefined,而不是指向window
  2. 浏览器加载 ES6 模块,也可以使用<script>标签,但是要加入type="module"属性。
<script type="module" src="./foo.js"></script>
  1. 浏览器对于带有type="module"<script>,都是异步加载,不会造成堵塞浏览器,即等到整个页面渲染完,再执行模块脚本,等同于打开了<script>标签的defer属性。