在建立 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
着重注意以下幾點:
- 在你的 HTML 中需要包含 type="module" 的 <script> 元素這樣的腳本,以便它被識别為子產品并正确處理
- 不能通過 file:// URL 運作 JS 子產品 — 這将導緻 CORS 錯誤。你需要通過 HTTP 伺服器運作。
使用預設導出
如果我們要導出一個值或得到子產品中的傳回值,就可以使用預設導出:
// 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: 導出 myFunction 和 myVariable
- childModule2.js: 導出 myClass
- parentModule.js: 作為聚合器(不做其他事情)
- 頂層子產品:調用 parentModule.js 的導出項
你的代碼看起來應該像這樣:
// 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 # sec-exports |
浏覽器相容性
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 Internet | 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.