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;