admin管理员组

文章数量:815012

节点代表中的奇怪(let)变量分配行为

我正在Windows 10中的cmd中使用Node v12.14.1。将未定义函数的值分配给变量时:

let a = f();

我得到:

Thrown:
ReferenceError: f is not defined

哪个很好。但是当我尝试时:

a = 2;

我现在得到:

Thrown:
ReferenceError: a is not defined

当我尝试时:

let a = 2;

我得到:

Thrown:
SyntaxError: Identifier 'a' has already been declared

因此,使用let声明的变量在分配了未定义函数的值时,已经同时声明了其标识符,并且未定义该标识符。这是故意的吗?我在这里想念什么吗?这是错误吗?当在未定义的函数分配中使用var或不使用任何内容(全局变量)时,不会发生相同的情况。

回答如下:

REPL很有趣,但是不,此行为不是错误,确实是根据规范。但是,这是在非REPL环境中看不到的东西。

let语句会在进入let出现的作用域时创建绑定¹,但不会对其进行初始化(与var不同,后者使用undefined对其进行初始化)。初始化发生在let语句的初始化部分发生时,随后是在逐步执行中到达该语句的时候。²但是,在代码中,您永远不会到达该语句的那部分,因为当对初始化程序进行了评估,它引发了错误。

那时,a不能做任何事情,因为它存在但尚未初始化,并且是唯一[对其进行初始化的东西(原始let a = f();中初始化器的结果)失败,无法再次运行。

之所以无法在非REPL代码中看到,是因为该错误使您脱离了已创建但尚未初始化a的范围。考虑:

try { let a = f(); // ReferenceError // Execution in this block never continues } catch { // Execution arrives here...but `a` is not in scope }


¹

binding

-执行上下文的environment record]中变量的条目²如果let语句没有初始化程序,则此时使用undefined

本文标签: 节点代表中的奇怪(let)变量分配行为