参考错误:初始化之前无法访问词法声明 'X'
当词法变量在初始化之前被访问时,会发生 JavaScript 异常 "初始化之前无法访问词法声明 'X'"。当 let
或 const
变量在声明它们的位置执行之前被访问时,这种情况会在任何范围(全局、模块、函数或块)内发生。
¥The JavaScript exception "can't access lexical declaration 'X' before initialization" occurs when a lexical variable was accessed before it was initialized.
This happens within any scope (global, module, function, or block) when let
or const
variables are accessed before the place where they are declared is executed.
信息
错误类型
什么地方出了错?
¥What went wrong?
词法变量在初始化之前被访问。当使用 let
或 const
声明的变量在声明它们的位置执行之前被访问时,这种情况会在任何范围(全局、模块、函数或块)内发生。
¥A lexical variable was accessed before it was initialized.
This happens within any scope (global, module, function, or block) when variables declared with let
or const
are accessed before the place where they are declared has been executed.
请注意,重要的是访问和变量声明的执行顺序,而不是语句在代码中出现的顺序。更多信息请参见 颞死区 的描述。
¥Note that it is the execution order of access and variable declaration that matters, not the order in which the statements appear in the code. For more information, see the description of Temporal Dead Zone.
使用 var
声明的变量不会出现此问题,因为当它们是 hoisted 时,它们会使用默认值 undefined
进行初始化。
¥This issue does not occur for variables declared using var
, because they are initialized with a default value of undefined
when they are hoisted.
当模块使用依赖于正在评估的模块本身的变量时,在 循环导入 中也可能会出现此错误。
¥This error can also occur in cyclic imports when a module uses a variable that depends on the module itself being evaluated.
示例
无效案例
¥Invalid cases
在本例中,变量 foo
在声明之前被访问。此时 foo 尚未使用值进行初始化,因此访问该变量会引发引用错误。
¥In this case, the variable foo
is accessed before it is declared.
At this point foo has not been initialized with a value, so accessing the variable throws a reference error.
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
的计算阻止。
¥In this example, the imported variable a
is accessed but is uninitialized, because the evaluation of a.js
is blocked by the evaluation of the current module b.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;
有效案例
¥Valid cases
在下面的示例中,我们在访问变量之前使用 const
关键字正确声明了该变量。
¥In the following example, we correctly declare a variable using the const
keyword before accessing it.
function test() {
// Declaring variable foo
const foo = 33;
console.log(foo); // 33
}
test();
在此示例中,导入的变量 a
是异步访问的,因此两个模块都会在访问 a
之前进行评估。
¥In this example, the imported variable a
is asynchronously accessed, so both modules are evaluated before the access to a
occurs.
// -- 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;