循环和局部变量内部的闭包

Closures inside loops and local variables

本文关键字:闭包 内部 局部变量 循环      更新时间:2023-11-14

我是一名JS新手,我读过关于闭包的文章,这是由于误解闭包的工作方式而出现的常见问题,"在循环中设置处理程序"就是一个很好的例子。我还看到并理解了绕过这一问题的方法,即调用另一个函数,将循环变量作为参数传递并返回一个函数。然后我试着尝试一下,看看是否有其他方法可以绕过这一点,我创建了以下代码。

var i;
var inpArr = new Array();
for(i = 0; i < 10; ++i) {
  inpArr.push(document.createElement("input"));
  inpArr[i].setAttribute("value", i);
  inpArr[i].onclick = function() {
    var index = i;
    alert("You clicked " + index);
  }
  document.body.appendChild(inpArr[i]);
}

我猜它不起作用,但我不明白为什么。据我所知,i已被捕获并可用于生成的所有函数表达式。但是,为什么在将捕获的变量分配给局部变量index之后,这仍然不起作用?分配i不是和将i作为参数传递给另一个函数一样吗?我的意思是,i不是一个原语吗?它不应该被复制吗?

我很困惑,如果有人能告诉我这里发生了什么,我真的很感激。

我认为您期望在循环的每一次迭代中都执行var index = i;,通过为不同的index变量设置不同的值,但事实并非如此。在每次迭代过程中,只有函数被分配给处理程序,函数不会运行。

这句话只有在你点击时才会执行,到那时i的值已经是你循环中的最高值了。这个确切的问题是通过你读到的解决方案来解决的。

循环过程中会发生什么:

inpArr[0].onclick = <a function>; //(local)index=undefined; i=0;
inpArr[1].onclick = <a function>; //(local)index=undefined; i=1;
inpArr[2].onclick = <a function>; //(local)index=undefined; i=2;
inpArr[3].onclick = <a function>; //(local)index=undefined; i=3;
.
.
inpArr[9].onclick = <a function>; //(local)index=undefined; i=9;

当你点击

index = i; //i=9; (local)index=9;