Javascript 具有意外结果的Closure和let关键字

Javascript 具有意外结果的Closure和let关键字,javascript,closures,Javascript,Closures,下面的代码如何在不同的i值上创建闭包?据我所知,闭包是当一个函数记住了它的词法范围时,即使该函数是在它的词法范围之外执行的。声明循环时,让我们创建一个名为i的块范围变量。但这种声明只会发生一次。根据这种逻辑,我希望这个循环记录为5 5 5,但它记录为0 1 2 3 4。如果我在循环中声明了新变量,让j=I并将其传递到console.log(j),那么我会理解输出是0 1 2 3 4,因为每次迭代都会创建一个新的块范围变量,并且函数会在该变量上关闭。但是,当整个块范围只创建一个i变量时,下面的内容

下面的代码如何在不同的i值上创建闭包?据我所知,闭包是当一个函数记住了它的词法范围时,即使该函数是在它的词法范围之外执行的。声明循环时,让我们创建一个名为i的块范围变量。但这种声明只会发生一次。根据这种逻辑,我希望这个循环记录为5 5 5,但它记录为0 1 2 3 4。如果我在循环中声明了新变量,让j=I并将其传递到console.log(j),那么我会理解输出是0 1 2 3 4,因为每次迭代都会创建一个新的块范围变量,并且函数会在该变量上关闭。但是,当整个块范围只创建一个i变量时,下面的内容如何结束不同的i变量?我错过了什么

for(let i = 0; i<5;i++){
    setTimeout(function(){
        console.log(i);
    },i*1000);
}

for(let i=0;ifor循环头中使用的let声明定义了一种特殊行为。这种行为表示,变量不仅会在循环中声明一次,还会在每次迭代中声明一次。而且,它将在每次后续迭代中使用上一次迭代结束时的值进行初始化,这将非常有用

您可以从此URL获取引用:

for循环初始化部分的声明之所以神奇,是因为这个原因。@Ry-即使如此,i的声明也会发生一次。我的意思是,词法范围中有一个i,而不是5个。我能说什么呢?这很神奇。请参阅的特定词汇声明变体,以及相应的(用于BodyEvaluation和CreatePacificationEnvironment的包操作绑定)。每次迭代都会创建一个新范围,并且以前的
i
值会复制到新范围中(当然是递增的,不确定是在之前还是之后)。将代码粘贴到中,应该会变得非常清楚。