将for循环块中的所有块作用域变量都挂载在循环标题本身之上?将ES6 javascript块作用域变量挂载到标题中
var x = 4;
for(let i = 3; i < x; i++) {
let x = 2;
...
}
这应该在每次将x与循环头中的x进行比较时在x上产生死区错误吗?我知道我被推倒在块范围内,但为什么不是x?
将for循环块中的所有块作用域变量都挂载在循环标题本身之上?将ES6 javascript块作用域变量挂载到标题中
var x = 4;
for(let i = 3; i < x; i++) {
let x = 2;
...
}
这应该在每次将x与循环头中的x进行比较时在x上产生死区错误吗?我知道我被推倒在块范围内,但为什么不是x?
for循环块中的所有块范围变量是否悬挂在循环头本身之上?
不,他们都悬挂在该块范围
如果这产生每一次X上的一个死区错误我是相比于环头X?我知道我被推倒在块范围内,但为什么不是x?
没有,因为x
在环头被引用定义为4 var x = 4
之前它已被宣布为确定范围和声明之间的时间无法访问let
变量x
是TDZ。
ex。
console.log(x) // Reference Error, x is in TDZ
let x = 4
console.log(x) // --> 4
我误解了,认为只会有一个块范围。我不愿意采用表达式i < x
中的两个任意变量,而必须决定查找哪个块范围,这是无法确定的。
正确的方法是构建两个嵌套块作用域,一个用于循环头,一个用于循环体。这意味着let i
在循环头文件和循环体范围中均可见,并且循环中的let x
仅在循环体范围中可见。容易peasy,柠檬squeezy。
语言规范的相关部分是13.7.4
如果for
语句包含let
或const
声明,然后创建一个范围。
如果for
语句包含let
声明,则每次迭代都会创建一个作用域。
如果for body是一个块,则创建一个范围。
下面是一些例子和所创建的范围:
//no scope
for(i = 0; i<3; i++) console.log(i);
//no scope
for(var i = 0; i<3; i++) console.log(i);
//for scope and iteration scope
for(let i = 0; i<3; i++) console.log(i);
// for scope, iteration scope and block scope
for(let i = 0; i<3; i++) {
console.log(i);
}
为什么我们需要迭代范围?关闭:
for(let i = 0; i<3; i++) {
setTimeout(() => console.log(i), 10);
}
无迭代范围输出:3,3,3。随着迭代范围:0,1,2
感谢您指出相关的ECMA标准部分。正如我猜测的那样,创建嵌套的作用域,一个用于任何循环头“let”,然后如果需要,第二个嵌套的作用域,用于循环体中的任何'let'。 – Malbrain
你想达到什么目的? – guest271314
我正在添加块范围变量到我的JavaScript数据库解释器,我需要知道如何正确处理这种情况。但是,我认为正确的方法是将循环块嵌套到循环头中。通过这种方式,可以在循环块中看到标题中的“let i”,但循环块中的“let x”在循环标题中不可见。 – Malbrain
不确定是什么问题?如果在'for'循环的外部定义了'var x = 4',为什么要在for循环中定义'let x = 2'? – guest271314