ReferenceError: can't access lexical declaration 'X' before initialization
JavaScript 異常“無法在初始化前訪問詞法宣告 'X'”發生在詞法變數在初始化前被訪問時。當在變數宣告的位置執行之前,訪問了使用 let 或 const 宣告的變數時,這種情況會在任何作用域(全域性、模組、函式或塊)內發生。
訊息
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
哪裡出錯了?
詞法變數在初始化之前被訪問。當在宣告變數的位置執行之前,訪問了使用 let 或 const 宣告的變數時,這種情況會在任何作用域(全域性、模組、函式或塊)內發生。
請注意,重要的是訪問和變數宣告的執行順序,而不是語句在程式碼中出現的順序。有關更多資訊,請參閱 暫時性死區 的描述。
使用 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;