在javascript中一个文件为一个独立的模块,要想在文件外部访问其他文件的内容,需要使用import导入外部模块,使用export导出对应的模块。

1.export命令

下面代码使用export导出变量

1
2
3
export let name = "Bob";
export let age = 25;
export let birthday = "2012-12-05";

除了上面的写法,我们更推荐下面这种写法

1
2
3
4
5
let name = "Bob";
let age = 25;
let birthday = "2012-12-05";

export { name, age, birthday };

以上两种写法是等价的,但是我们更推荐第二种,因为第二种写法能更加直观的看出需要输出哪些变量。

export命令除了输出变量之外,还可以输出函数、class类等

1
2
3
export function sum(x, y){
return x + y;
}

除了输出函数本来的名称之外,我们还可以使用as关键字给输出的函数重命名

1
2
3
4
function f1(){ //... }
function f2(){ //... }

export { f1 as func1, f2 as func2 }

注意的是export命令规定的是对外输出的接口,必须与模块内部的变量建立一一对应的关系,我们把一个对象想象为一个映射关系,就不难理解了。下面这类写法,就是错误的。

1
2
3
4
5
6
7
8
// 报错
export 666;
// 报错
let num = 7;
export num;
// 报错
function f1(){ //... }
export f1;

2.import命令

使用export定义了对外接口之后,可以使用import加载这个模块

1
2
3
import { sum } from './test.js';

sum(1, 2); // 3

我们也可以使用as关键字对导入的模块进行重命名

1
2
3
import { sum as myFun } from './test.js';

myFun(1, 2); // 3

import命令导入的内容是只读的,因为它的本质是输入接口。也就是说,不允许在加载模块的脚本里面,改写接口。

1
2
3
import { a } from './test.js';

a = {}; //报错

但是如果导入的内容是一个对象,我们进行对象属性的改写,这是允许的操作。

1
2
3
import { obj } from './test.js';

obj.attr1 = 6; //合法

虽然对导入对象的属性改写是合法的,在其他模块中也能读取到这里的改写,但这类操作导致错误难以追踪,为了程序的可维护性,我们建议导入的内容执行只读操作,不轻易做更改。

3.模块的整体加载

除了上面案例中的一一对应加载,我们还可以使用*符号指定一个对象整体加载模块。

1
2
3
4
5
6
7
// all.js
export function sum(x, y){
return x + y;
}
export function multiply(x, y){
return x * y;
}

下面整体加载该模块

1
2
3
4
import * as all from './all.js';

all.sum(1, 2); // 3
all.multiply(1, 2); // 2

4.export default

到这为止,上面的案例导入时都需要知道内容的名称,使用export default命令,默认导出default名称的内容,我们可以给导入的模块取任意名称。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
export default function fn(){
// ...
}

import myfn from './test.js';
``

上面代码中,函数名fn在外部是无效的,加载该模块的时候,视匿名函数加载,我们对比一下正常输出和默认输出
```javascript
// 正常输出
export function fn(){
//...
}

import { fn } from './test.js';

// 默认输出
export default function fn(){
// ...
}

import myfn from './test.js';

上面两组代码,使用export default输出时,import导入不需要大括号,而使用export时则需要;export default默认输出时只允许一个输出,而使用export正常输出可以有多个。