我知道这let可以防止重复声明,这很好。
let
let x; let x; // error!
用声明的变量let也可以在可以预期的闭包中使用
let i = 100; setTimeout(function () { console.log(i) }, i); // '100' after 100 ms
我有点难以掌握的是如何let应用于循环。这似乎是特定于for循环的。考虑经典问题:
for
// prints '10' 10 times for (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的语法糖吗?这如何运作?
我了解和之间的区别var,let并在上面进行了说明。我特别想了解为什么不同的声明使用for循环会导致不同的输出。
var
这只是ES6的语法糖吗?
不,它不仅仅是语法糖。详细资料埋在§13.6.3.9中 CreatePerIterationEnvironment。
CreatePerIterationEnvironment
这如何运作?
如果let在for语句中使用该关键字,它将检查其绑定的名称,然后
您的循环语句for (var i = 0; i < 10; i++) process.nextTick(_ =>console.log(i));简化为一个简单的
for (var i = 0; i < 10; i++) process.nextTick(_ =>console.log(i));
// omitting braces when they don't introduce a block var i; i = 0; if (i < 10) process.nextTick(_ => console.log(i)) i++; if (i < 10) process.nextTick(_ => console.log(i)) i++; …
while for (let i = 0; i < 10; i++) process.nextTick(_ => console.log(i)); does “desugar” to the much more complicated
for (let i = 0; i < 10; i++) process.nextTick(_ => console.log(i));
// using braces to explicitly denote block scopes, // using indentation for control flow { let i; i = 0; __status = {i}; } { let {i} = __status; if (i < 10) process.nextTick(_ => console.log(i)) __status = {i}; } { let {i} = __status; i++; if (i < 10) process.nextTick(_ => console.log(i)) __status = {i}; } { let {i} = __status; i++; …