用for循环解释‘let’和块范围

用for循环解释‘let’和块范围

我明白let防止重复声明,这是很好的。

let x;let x; // error!

声明变量let也可以在闭包中使用,这是可以预期的。

let i = 100;setTimeout(function () { console.log(i) }, i); // '100' after 100 ms

我有点难以把握的是let适用于循环。这似乎是特定于for循环。考虑一下经典的问题:

// prints '10' 10 timesfor (var i = 0; i < 10; i++) { process.nextTick(_ => console.log(i)) }
// prints '0' through '9'for (let i = 0; i < 10; i++) { process.nextTick(_ => console.log(i)) }

为什么使用let在这方面起作用了吗?在我的想象中,即使只有一个街区是可见的,for实际上为每个迭代创建一个单独的块,并且let声明是在那个块内完成的.。但只有一个let声明来初始化值。这只是ES6的语法糖吗?这是怎么回事?

我明白varlet并在上面作了说明。我特别感兴趣的是,为什么不同的声明使用for循环。


青春有我
浏览 587回答 3
3回答

慕斯709654

这只是ES6的语法糖吗?不,这不仅仅是语法糖。血淋淋的细节被埋葬在第13.6.3.9节CreatePerIterationEnvironment.这是怎么回事?如果你用那个let关键字中的for语句,它将检查它所绑定的名称,然后为a)初始化表达式b)每次迭代(以前用于计算增量表达式)创建一个具有这些名称的新的词法环境将具有这些名称的所有变量的值从一个复制到下一个环境。循环语句for (var i = 0; i < 10; i++) process.nextTick(_ => console.log(i));脱糖成一个简单的//&nbsp;omitting&nbsp;braces&nbsp;when&nbsp;they&nbsp;don't&nbsp;introduce&nbsp;a&nbsp;blockvar&nbsp;i;i&nbsp;=&nbsp;0;if&nbsp;(i&nbsp;<&nbsp;10) &nbsp;&nbsp;&nbsp;&nbsp;process.nextTick(_&nbsp;=>&nbsp;console.log(i)) &nbsp;&nbsp;&nbsp;&nbsp;i++; &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(i&nbsp;<&nbsp;10) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;process.nextTick(_&nbsp;=>&nbsp;console.log(i)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i++; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;…当for (let i = 0; i < 10; i++) process.nextTick(_ => console.log(i));对复杂得多的人来说//&nbsp;using&nbsp;braces&nbsp;to&nbsp;explicitly&nbsp;denote&nbsp;block&nbsp;scopes,//&nbsp;using&nbsp;indentation&nbsp;for&nbsp;control&nbsp;flow{&nbsp;let&nbsp;i; &nbsp;&nbsp;i&nbsp;=&nbsp;0; &nbsp;&nbsp;__status&nbsp;=&nbsp;{i};}{&nbsp;let&nbsp;{i}&nbsp;=&nbsp;__status; &nbsp;&nbsp;if&nbsp;(i&nbsp;<&nbsp;10) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;process.nextTick(_&nbsp;=>&nbsp;console.log(i)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__status&nbsp;=&nbsp;{i};}&nbsp;&nbsp;&nbsp;{&nbsp;let&nbsp;{i}&nbsp;=&nbsp;__status; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i++; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(i&nbsp;<&nbsp;10) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;process.nextTick(_&nbsp;=>&nbsp;console.log(i)) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__status&nbsp;=&nbsp;{i}; &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;{&nbsp;let&nbsp;{i}&nbsp;=&nbsp;__status; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i++; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;…

陪伴而非守候

我发现这是从探索ES6书中得到的解释。最好的:var-在for循环的头上声明一个变量将为该变量创建单个绑定(存储空间):const&nbsp;arr&nbsp;=&nbsp;[];for&nbsp;(var&nbsp;i=0;&nbsp;i&nbsp;<&nbsp;3;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;arr.push(()&nbsp;=>&nbsp;i);}arr.map(x&nbsp;=>&nbsp;x());&nbsp;//&nbsp;[3,3,3]三个箭头函数体中的每个I都引用相同的绑定,这就是它们都返回相同值的原因。如果让-声明一个变量,则为每个循环迭代创建一个新的绑定:const&nbsp;arr&nbsp;=&nbsp;[];for&nbsp;(let&nbsp;i=0;&nbsp;i&nbsp;<&nbsp;3;&nbsp;i++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;arr.push(()&nbsp;=>&nbsp;i);}arr.map(x&nbsp;=>&nbsp;x());&nbsp;//&nbsp;[0,1,2]这一次,每个我都提到一个特定迭代的绑定,并保留当时的值。因此,每个箭头函数返回不同的值。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript