在创建JavaScript模块时,export
用于从模块中导出实时绑定的函数、对象或原始值,以便其他程序可以通过 import
使用它们。
被导出的绑定值依然可以在本地进行修改。
在使用import 进行导入时,这些绑定值只能被导入模块所读取,但在 export 导出模块中对这些绑定值进行修改,所修改的值也会实时地更新。
exports
ES6模块只支持静态导出,只可以在模块的最外层作用域使用export
,不可在条件语句与函数作用域中使用。
Named exports (命名导出)
这种方式主要用于导出多个函数或者变量, 明确知道导出的变量名称。
使用:只需要在变量或函数前面加 export
关键字即可。
使用场景:比如 utils、tools、common 之类的工具类函数集,或者全站统一变量等。
- export 后面不可以是表达式,因为表达式只有值,没有名字。
- 每个模块包含任意数量的导出。
// lib.js
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
// index.js 使用方式1
import { square, diag } from 'lib';
console.log(square(11)); // 121
// index.js 使用方式2
import * as lib from 'lib';
console.log(lib.square(11)); // 121
简写格式,统一列出需要输出的变量,例如上面的lib.js可以改写成:
// lib.js
const sqrt = Math.sqrt;
function square(x) {
return x * x;
}
function add (x, y) {
return x + y;
}
export { sqrt, square, add };
Default exports (默认导出)
这种方式主要用于导出类文件或一个功能比较单一的函数文件;
使用:只需要在变量或函数前面加 export default
关键字即可。
- 每个模块最多只能有一个默认导出;
- 默认导出可以视为名字是
default
的模块输出变量;- 默认导出后面可以是表达式,因为它只需要值。
导出一个值:
export default 123;
导出一个函数:
// myFunc.js
export default function () { ... };
// index.js
import myFunc from 'myFunc';
myFunc();
导出一个类:
// MyClass.js
class MyClass{
constructor() {}
}
export default MyClass;
// 或者
export { MyClass as default, … };
// index.js
import MyClass from 'MyClass';
export default 与 export 的区别:
- 不需要知道导出的具体变量名;
- 导入【import】时不需要 { } 包裹;
Combinations exports (混合导出)
混合导出是 Named exports
和 Default exports
组合导出。
混合导出后,默认导入一定放在命名导入前面;
// lib.js
export const myValue = '';
export const MY_CONST = '';
export function myFunc() {
...
}
export function* myGeneratorFunc() {
...
}
export default class MyClass {
...
}
// index.js
import MyClass, { myValue, myFunc } from 'lib';
Re-exporting (别名导出)
一般情况下,export 导出的变量名是原文件中的变量名,但也可以用 as 关键字来指定别名。这样做是为了简化或者语义化 export 的函数名。
同一个变量允许使用不同名字输出多次
// lib.js
function getName() {
...
};
function setName() {
...
};
export {
getName as get,
getName as getUserName,
setName as set
}
Module Redirects (中转模块导出)
为了方便使用模块导入,在一个父模块中“导入-导出”不同模块。简单来说:创建单个模块,集中多个模块的多个导出。
使用:使用 export from
语法实现;
export * from 'lib'; // 没有设置 export default
export * as myFunc2 from 'myFunc'; // 【ES2021】没有设置 export default
export { default as function1, function2 } from 'bar.js';
上述例子联合使用导入和导出:
import { default as function1, function2 } from 'bar.js';
export { function1, function2 };
尽管此时 export 与 import 等效,但以下语法在语法上无效:
import DefaultExport from 'bar.js'; // 有效的
export DefaultExport from 'bar.js'; // 无效的
正确的做法是重命名这个导出:
export { default as DefaultExport } from 'bar.js';
Importing
// Named imports
import { foo, bar as b } from './some-module.mjs';
// Namespace import
import * as someModule from './some-module.mjs';
// Default import
import someModule from './some-module.mjs';
// Combinations:
import someModule, * as someModule from './some-module.mjs';
import someModule, { foo, bar as b } from './some-module.mjs';
// Empty import (for modules with side effects)
import './some-module.mjs';