在創(chuàng)建 JAVAScript 模塊時(shí),export 語(yǔ)句用于從模塊中導(dǎo)出實(shí)時(shí)綁定的函數(shù)、對(duì)象或原始值,以便其他程序可以通過(guò) import 語(yǔ)句使用它們。被導(dǎo)出的綁定值依然可以在本地進(jìn)行修改。在使用 import 進(jìn)行導(dǎo)入時(shí),這些綁定值只能被導(dǎo)入模塊所讀取,但在 export 導(dǎo)出模塊中對(duì)這些綁定值進(jìn)行修改,所修改的值也會(huì)實(shí)時(shí)地更新。
無(wú)論您是否聲明,導(dǎo)出的模塊都處于嚴(yán)格模式。 export 語(yǔ)句不能用在嵌入式腳本中。
語(yǔ)法
存在兩種 exports 導(dǎo)出方式:
- 命名導(dǎo)出(每個(gè)模塊包含任意數(shù)量)
- 默認(rèn)導(dǎo)出(每個(gè)模塊包含一個(gè))
// 導(dǎo)出單個(gè)特性
export let name1, name2, …, nameN; // also var, const
export let name1 = …, name2 = …, …, nameN; // also var, const
export function FunctionName(){...}
export class ClassName {...}
// 導(dǎo)出列表
export { name1, name2, …, nameN };
// 重命名導(dǎo)出
export { variable1 as name1, variable2 as name2, …, nameN };
// 解構(gòu)導(dǎo)出并重命名
export const { name1, name2: bar } = o;
// 默認(rèn)導(dǎo)出
export default expression;
export default function (…) { … } // also class, function*
export default function name1(…) { … } // also class, function*
export { name1 as default, … };
// 導(dǎo)出模塊合集
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
要導(dǎo)出的標(biāo)識(shí)符(以便其他腳本通過(guò) import 語(yǔ)句進(jìn)行導(dǎo)入).
描述
有兩種不同的導(dǎo)出方式,命名導(dǎo)出和默認(rèn)導(dǎo)出。你能夠在每一個(gè)模塊中定義多個(gè)命名導(dǎo)出,但是只允許有一個(gè)默認(rèn)導(dǎo)出。每種方式對(duì)應(yīng)于上述的一種語(yǔ)法:
命名導(dǎo)出:
// 導(dǎo)出事先定義的特性
export { myFunction, myVariable };
// 導(dǎo)出單個(gè)特性(可以導(dǎo)出 var,let,
//const,function,class)
export let myVariable = Math.sqrt(2);
export function myFunction() { ... };
Copy to Clipboard
默認(rèn)導(dǎo)出:
// 導(dǎo)出事先定義的特性作為默認(rèn)值
export { myFunction as default };
// 導(dǎo)出單個(gè)特性作為默認(rèn)值
export default function () { ... }
export default class { .. }
// 每個(gè)導(dǎo)出都覆蓋前一個(gè)導(dǎo)出
Copy to Clipboard
在導(dǎo)出多個(gè)值時(shí),命名導(dǎo)出非常有用。在導(dǎo)入期間,必須使用相應(yīng)對(duì)象的相同名稱。
但是,可以使用任何名稱導(dǎo)入默認(rèn)導(dǎo)出,例如:
// 文件 test.js
let k; export default k = 12;
Copy to Clipboard
// 另一個(gè)文件
import m from './test'; // 由于 k 是默認(rèn)導(dǎo)出,所以可以自由使用 import m 替代 import k
console.log(m); // 輸出為 12
Copy to Clipboard
你也可以重命名命名導(dǎo)出以避免命名沖突:
export { myFunction as function1,
myVariable as variable };
Copy to Clipboard
重導(dǎo)出 / 聚合
為了使模塊導(dǎo)入變得可用,在一個(gè)父模塊中“導(dǎo)入/導(dǎo)出”這些不同模塊也是可行的。也就是說(shuō),你可以創(chuàng)建單個(gè)模塊,集中多個(gè)模塊的多個(gè)導(dǎo)出。
這個(gè)可以使用“export from”語(yǔ)法實(shí)現(xiàn):
export { default as function1,
function2 } from 'bar.js';
Copy to Clipboard
與之形成對(duì)比的是聯(lián)合使用導(dǎo)入和導(dǎo)出:
import { default as function1,
function2 } from 'bar.js';
export { function1, function2 };
Copy to Clipboard
但這里的 function1 和 function2 在當(dāng)前模塊中變得不可用。
備注: 盡管與 import 等效,但以下語(yǔ)法在語(yǔ)法上無(wú)效:
import DefaultExport from 'bar.js'; // 有效的
Copy to Clipboard
export DefaultExport from 'bar.js'; // 無(wú)效的
Copy to Clipboard
這里正確的做法是重命名這個(gè)導(dǎo)出:
export { default as DefaultExport } from 'bar.js';
Copy to Clipboard
示例
使用命名導(dǎo)出
在模塊 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 頁(yè)面的頂級(jí)模塊中:
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
著重注意以下幾點(diǎn):
- 在你的 HTML 中需要包含 type="module" 的 <script> 元素這樣的腳本,以便它被識(shí)別為模塊并正確處理
- 不能通過(guò) file:// URL 運(yùn)行 JS 模塊 — 這將導(dǎo)致 CORS 錯(cuò)誤。你需要通過(guò) HTTP 服務(wù)器運(yùn)行。
使用默認(rèn)導(dǎo)出
如果我們要導(dǎo)出一個(gè)值或得到模塊中的返回值,就可以使用默認(rèn)導(dǎo)出:
// module "my-module.js"
export default function cube(x) {
return x * x * x;
}
Copy to Clipboard
然后,在另一個(gè)腳本中,可以直接導(dǎo)入默認(rèn)導(dǎo)出:
import cube from './my-module.js';
console.log(cube(3)); // 27
Copy to Clipboard
模塊重定向
舉個(gè)例子,假如我們有如下層次結(jié)構(gòu):
- childModule1.js: 導(dǎo)出 myFunction 和 myVariable
- childModule2.js: 導(dǎo)出 myClass
- parentModule.js: 作為聚合器(不做其他事情)
- 頂層模塊:調(diào)用 parentModule.js 的導(dǎo)出項(xiàng)
你的代碼看起來(lái)應(yīng)該像這樣:
// 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 中的導(dǎo)出
// 以重新導(dǎo)出他們
export { myFunction, myVariable } from 'childModule1.js';
export { myClass } from 'childModule2.js';
Copy to Clipboard
// 頂層模塊中
// 我們可以從單個(gè)模塊調(diào)用所有導(dǎo)出,因?yàn)?parentModule 事先
// 已經(jīng)將他們“收集”/“打包”到一起
import { myFunction, myVariable, myClass } from 'parentModule.js'
Copy to Clipboard
規(guī)范
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 |
Legend
Tip: you can click/tap on a cell for more information.