導入模組是否意味著將模組的程式碼嵌入到導入語句所在的行嗎?
P粉269847997
P粉269847997 2023-09-16 18:25:30
0
1
433

從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中的行不會改變結果。

P粉269847997
P粉269847997

全部回覆(1)
P粉165823783

從導入的模組中的程式碼不僅僅是嵌入("貼上"),而是存在於一個獨立的閉包中。雖然這肯定是一個過度簡化,但我將模組與函數進行比較,將export語句與其return語句進行比較:

function a_js() {
  var b = b_js(); // 不必要的行
  return 2;
}

function b_js() {
  var a = a_js();
  console.log(a);
  return 1;
}
<button onclick="a_js()">import a.js</button>
<button onclick="b_js()">import b.js</button>

因為模組相互導入,它們不能以任何順序載入:按下任何按鈕都會導致"Maximum call stack size exceeded"錯誤。

但是如果你刪除不必要的行(只是填充一個然後被丟棄的局部變數),它就可以工作。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板