ReferenceError: can't access lexical declaration 'X' before initialization

JavaScript 異常“無法在初始化前訪問詞法宣告 'X'”發生在詞法變數在初始化前被訪問時。當在變數宣告的位置執行之前,訪問了使用 letconst 宣告的變數時,這種情況會在任何作用域(全域性、模組、函式或塊)內發生。

訊息

ReferenceError: Cannot access 'X' before initialization (V8-based)
ReferenceError: can't access lexical declaration 'X' before initialization (Firefox)
ReferenceError: Cannot access uninitialized variable. (Safari)

錯誤型別

ReferenceError

哪裡出錯了?

詞法變數在初始化之前被訪問。當在宣告變數的位置執行之前,訪問了使用 letconst 宣告的變數時,這種情況會在任何作用域(全域性、模組、函式或塊)內發生。

請注意,重要的是訪問和變數宣告的執行順序,而不是語句在程式碼中出現的順序。有關更多資訊,請參閱 暫時性死區 的描述。

使用 var 宣告的變數不會出現此問題,因為它們在 變數提升 時會用預設值 undefined 進行初始化。

當一個模組使用依賴於模組本身進行評估的變數時,此錯誤也可能發生在 迴圈匯入 中。

示例

無效案例

在此情況下,變數 foo 在宣告之前被訪問。此時 foo 尚未用值進行初始化,因此訪問該變數會丟擲引用錯誤。

js
function test() {
  // Accessing the 'const' variable foo before it's declared
  console.log(foo); // ReferenceError: foo is not initialized
  const foo = 33; // 'foo' is declared and initialized here using the 'const' keyword
}

test();

在此示例中,匯入的變數 a 被訪問但未初始化,因為 a.js 的評估被當前模組 b.js 的評估所阻塞。

js
// -- a.js (entry module) --
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;

有效情況

在以下示例中,我們在訪問變數之前,使用 const 關鍵字正確聲明瞭變數。

js
function test() {
  // Declaring variable foo
  const foo = 33;
  console.log(foo); // 33
}
test();

在此示例中,匯入的變數 a 是非同步訪問的,因此在訪問 a 之前,兩個模組都會進行評估。

js
// -- a.js (entry module) --
import { b } from "./b.js";

export const a = 2;

// -- b.js --
import { a } from "./a.js";

setTimeout(() => {
  console.log(a); // 2
}, 10);
export const b = 1;

另見