在创建 JAVAScript 模块时,export 语句用于从模块中导出实时绑定的函数、对象或原始值,以便其他程序可以通过 import 语句使用它们。被导出的绑定值依然可以在本地进行修改。在使用 import 进行导入时,这些绑定值只能被导入模块所读取,但在 export 导出模块中对这些绑定值进行修改,所修改的值也会实时地更新。
无论您是否声明,导出的模块都处于严格模式。 export 语句不能用在嵌入式脚本中。
存在两种 exports 导出方式:
// 导出单个特性
export let name1, name2, …, nameN; // also var, const
export let name1 = …, name2 = …, …, nameN; // also var, const
export function FunctionName(){...}
export class ClassName {...}
// 导出列表
export { name1, name2, …, nameN };
// 重命名导出
export { variable1 as name1, variable2 as name2, …, nameN };
// 解构导出并重命名
export const { name1, name2: bar } = o;
// 默认导出
export default expression;
export default function (…) { … } // also class, function*
export default function name1(…) { … } // also class, function*
export { name1 as default, … };
// 导出模块合集
export * from …; // does not set the default export
export * as name1 from …; // Draft ECMAScript® 2O21
export { name1, name2, …, nameN } from …;
export { import1 as name1, import2 as name2, …, nameN } from …;
export { default } from …;
Copy to Clipboard
nameN
要导出的标识符(以便其他脚本通过 import 语句进行导入).
有两种不同的导出方式,命名导出和默认导出。你能够在每一个模块中定义多个命名导出,但是只允许有一个默认导出。每种方式对应于上述的一种语法:
命名导出:
// 导出事先定义的特性
export { myFunction, myVariable };
// 导出单个特性(可以导出 var,let,
//const,function,class)
export let myVariable = Math.sqrt(2);
export function myFunction() { ... };
Copy to Clipboard
默认导出:
// 导出事先定义的特性作为默认值
export { myFunction as default };
// 导出单个特性作为默认值
export default function () { ... }
export default class { .. }
// 每个导出都覆盖前一个导出
Copy to Clipboard
在导出多个值时,命名导出非常有用。在导入期间,必须使用相应对象的相同名称。
但是,可以使用任何名称导入默认导出,例如:
// 文件 test.js
let k; export default k = 12;
Copy to Clipboard
// 另一个文件
import m from './test'; // 由于 k 是默认导出,所以可以自由使用 import m 替代 import k
console.log(m); // 输出为 12
Copy to Clipboard
你也可以重命名命名导出以避免命名冲突:
export { myFunction as function1,
myVariable as variable };
Copy to Clipboard
为了使模块导入变得可用,在一个父模块中“导入/导出”这些不同模块也是可行的。也就是说,你可以创建单个模块,集中多个模块的多个导出。
这个可以使用“export from”语法实现:
export { default as function1,
function2 } from 'bar.js';
Copy to Clipboard
与之形成对比的是联合使用导入和导出:
import { default as function1,
function2 } from 'bar.js';
export { function1, function2 };
Copy to Clipboard
但这里的 function1 和 function2 在当前模块中变得不可用。
备注: 尽管与 import 等效,但以下语法在语法上无效:
import DefaultExport from 'bar.js'; // 有效的
Copy to Clipboard
export DefaultExport from 'bar.js'; // 无效的
Copy to Clipboard
这里正确的做法是重命名这个导出:
export { default as DefaultExport } from 'bar.js';
Copy to Clipboard
示例
在模块 my-module.js 中,可能包含以下代码:
// module "my-module.js"
function cube(x) {
return x * x * x;
}
const foo = Math.PI + Math.SQRT2;
var graph = {
options: {
color:'white',
thickness:'2px'
},
draw: function() {
console.log('From graph draw function');
}
}
export { cube, foo, graph };
Copy to Clipboard
然后,在你的 html 页面的顶级模块中:
import { cube, foo, graph } from 'my-module.js';
graph.options = {
color:'blue',
thickness:'3px'
};
graph.draw();
console.log(cube(3)); // 27
console.log(foo); // 4.555806215962888
Copy to Clipboard
着重注意以下几点:
如果我们要导出一个值或得到模块中的返回值,就可以使用默认导出:
// module "my-module.js"
export default function cube(x) {
return x * x * x;
}
Copy to Clipboard
然后,在另一个脚本中,可以直接导入默认导出:
import cube from './my-module.js';
console.log(cube(3)); // 27
Copy to Clipboard
举个例子,假如我们有如下层次结构:
你的代码看起来应该像这样:
// childModule1.js 中
let myFunction = ...; // assign something useful to myFunction
let myVariable = ...; // assign something useful to myVariable
export {myFunction, myVariable};
Copy to Clipboard
// childModule2.js 中
let myClass = ...; // assign something useful to myClass
export myClass;
Copy to Clipboard
// parentModule.js 中
// 仅仅聚合 childModule1 和 childModule2 中的导出
// 以重新导出他们
export { myFunction, myVariable } from 'childModule1.js';
export { myClass } from 'childModule2.js';
Copy to Clipboard
// 顶层模块中
// 我们可以从单个模块调用所有导出,因为 parentModule 事先
// 已经将他们“收集”/“打包”到一起
import { myFunction, myVariable, myClass } from 'parentModule.js'
Copy to Clipboard
Specification |
ECMAScript Language Specification |
Report problems with this compatibility data on Github
|
desktop |
mobile |
server |
||||||||||
|
Chrome |
Edge |
Firefox |
Opera |
Safari |
Chrome Android |
Firefox for Android |
Opera Android |
Safari on IOS |
Samsung Inte.NET |
WebView Android |
Deno |
Node.js |
export |
61 Toggle history |
16 Toggle history |
60 Toggle history |
48 Toggle history |
10.1 Toggle history |
61 Toggle history |
60 Toggle history |
45 Toggle history |
10.3 Toggle history |
8.0 Toggle history |
61 Toggle history |
1.0 Toggle history |
13.2.0 footnotemore Toggle history |
default keyword with export |
61 Toggle history |
16 Toggle history |
60 Toggle history |
48 Toggle history |
10.1 Toggle history |
61 Toggle history |
60 Toggle history |
45 Toggle history |
10.3 Toggle history |
8.0 Toggle history |
No Toggle history |
1.0 Toggle history |
13.2.0 footnotemore Toggle history |
export * as namespace |
72 Toggle history |
79 Toggle history |
80 Toggle history |
60 Toggle history |
14.1 Toggle history |
72 Toggle history |
80 Toggle history |
51 Toggle history |
14.5 Toggle history |
11.0 Toggle history |
No Toggle history |
1.0 Toggle history |
13.2.0 footnotemore Toggle history |
Tip: you can click/tap on a cell for more information.