javascript – 使用for循环的`let`和block作用域的解释

前端之家收集整理的这篇文章主要介绍了javascript – 使用for循环的`let`和block作用域的解释前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我明白,让我们避免重复的声明是不错的.
let x;
let x; // error!

用let声明的变量也可以用在可以预期的闭包中

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

我有一些困难抓住是如何适用于循环.这似乎是针对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工作?在我的想象中,即使只有一个块是可见的,实际上为每个迭代创建一个单独的块,并且let声明在该块内部完成…但是只有一个let声明来初始化该值.这只是ES6的语法糖吗?这是如何工作的?

我了解var和let之间的区别,并在上面说明了它们.我特别感兴趣的是,为什么不同的声明导致使用for循环的不同输出.

解决方法

Is this just syntactic sugar for ES6?

不,它超过了语法糖.血腥细节埋在§13.6.3.9
CreatePerIterationEnvironment
年.

How is this working?

如果在for语句中使用let关键字,它将检查它绑定的名称,然后

>为这些名称创建一个新的词汇环境a)初始化表达式b)每次迭代(以前用于评估递增表达式)
>将所有变量的值从这些名称复制到下一个环境

你的循环语句(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++;
        …

而对于(让i = 0; i <10; i){process.nextTick(_ => console.log(i))}对于更复杂的“desugar”

// 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++;
          …

猜你在找的JavaScript相关文章