從ReferenceError: can't access lexical declaration 'X' before initialization - JavaScript | MDN中,有一個無效導入的範例:
a.js
(入口模組):
import { b } from "./b.js"; export const a = 2;
b.js
:
import { a } from "./a.js"; console.log(a); // ReferenceError: Cannot access 'a' before initialization export const b = 1;
MDN解釋:
在這個例子中,導入的變數
a
被訪問,但是未初始化,因為a.js
的評估被當前模組b.js
的評估阻塞。
我理解這個意思是導入一個模組意味著將模組的程式碼嵌入到導入語句的行。也就是說,編譯時a.js
變成了這樣:
console.log(a); // ReferenceError: Cannot access 'a' before initialization const b = 1; const a = 2;
這個理解正確嗎?我沒有在import - JavaScript | MDN中看到這個解釋。由於變數提升,我不知道如何測試這個問題,因為重新排列a.js
中的行不會改變結果。
從導入的模組中的程式碼不僅僅是嵌入("貼上"),而是存在於一個獨立的閉包中。雖然這肯定是一個過度簡化,但我將模組與函數進行比較,將
export
語句與其return
語句進行比較:因為模組相互導入,它們不能以任何順序載入:按下任何按鈕都會導致"Maximum call stack size exceeded"錯誤。
但是如果你刪除不必要的行(只是填充一個然後被丟棄的局部變數),它就可以工作。