1、export 在介面名字與模塊內部的變數之間建立了一一對應的關係,export輸出的介面,與其模塊內對應的變數值是動態綁定的,即通過暴露的介面可以取到模塊內與之對應綁定變數的實時的值。 commonjs的規範完全不同,commonjs輸出的是值的緩存,不存在動態的更新。 export的寫法,除了 ...
1、export 在介面名字與模塊內部的變數之間建立了一一對應的關係,export輸出的介面,與其模塊內對應的變數值是動態綁定的,即通過暴露的介面可以取到模塊內與之對應綁定變數的實時的值。
commonjs的規範完全不同,commonjs輸出的是值的緩存,不存在動態的更新。
export var firstName = 'Michael'; export var lastName = 'Jackson'; export var year = 1958;
export
的寫法,除了像上面這樣,還有另外一種。
// profile.js var firstName = 'Michael'; var lastName = 'Jackson'; var year = 1958; export { firstName, lastName, year };
export
命令除了輸出變數,還可以輸出函數或類(class)。
export function multiply(x, y) { return x * y; };
2、CommonJS 和 AMD 模塊,都只能在運行時確定這些東西。比如,CommonJS 模塊就是對象,輸入時必須查找對象屬性。
/ CommonJS模塊 let { stat, exists, readFile } = require('fs'); // 等同於 let _fs = require('fs'); let stat = _fs.stat; let exists = _fs.exists; let readfile = _fs.readfile;
上面代碼的實質是整體載入fs
模塊(即載入fs
的所有方法),生成一個對象(_fs
),然後再從這個對象上面讀取 3 個方法。這種載入稱為“運行時載入”,因為只有運行時才能得到這個對象,導致完全沒辦法在編譯時做“靜態優化”。
// ES6模塊 import { stat, exists, readFile } from 'fs';
ES6 模塊不是對象,而是通過export
命令顯式指定輸出的代碼,再通過import
命令輸入。上面代碼的實質是從fs
模塊載入 3 個方法,其他方法不載入。這種載入稱為“編譯時載入”或者靜態載入,即 ES6 可以在編譯時就完成模塊載入,效率要比 CommonJS 模塊的載入方式高。當然,這也導致了沒法引用 ES6 模塊本身,因為它不是對象。
tips:import
語句會執行所載入的模塊,因此可以有下麵的寫法。
import 'lodash';
上面代碼僅僅執行lodash
模塊,但是不輸入任何值。
3、import
和export
命令只能在模塊的頂層,不能在代碼塊之中(比如,在if
代碼塊之中,或在函數之中)。這樣的設計,固然有利於編譯器提高效率,但也導致無法在運行時載入模塊。在語法上,條件載入就不可能實現。如果import
命令要取代 Node 的require
方法,這就形成了一個障礙。因為require
是運行時載入模塊,import
命令無法取代require
的動態載入功能。
const path = './' + fileName; const myModual = require(path);
上面的語句就是動態載入,require
到底載入哪一個模塊,只有運行時才知道。import
命令做不到這一點。
4、引入import()
函數,完成動態載入。
import
命令能夠接受什麼參數,import()
函數就能接受什麼參數,兩者區別主要是後者為動態載入。
import()
返回一個 Promise 對象。
import()
函數可以用在任何地方,不僅僅是模塊,非模塊的腳本也可以使用。它是運行時執行,也就是說,什麼時候運行到這一句,就會載入指定的模塊。
import()
類似於 Node 的require
方法,區別主要是前者是非同步載入,後者是同步載入。
下麵是import()
的一些適用場合。
1、按需載入
import()
可以在需要的時候,再載入某個模塊。
button.addEventListener('click', event => { import('./dialogBox.js') .then(dialogBox => { dialogBox.open(); }) .catch(error => { /* Error handling */ }) });
2、條件載入
import()
可以放在if
代碼塊,根據不同的情況,載入不同的模塊。
if (condition) { import('moduleA').then(...); } else { import('moduleB').then(...); }
import()
載入模塊成功以後,這個模塊會作為一個對象,當作then
方法的參數。因此,可以使用對象解構賦值的語法,獲取輸出介面。
import('./myModule.js') .then(({export1, export2}) => { // ...· });