JavaScript for循环索引奇怪

我对JS比较陌生,所以这可能是一个常见的问题,但是在处理for循环和onclick函数时我注意到了一些奇怪的东西。 我能够用这个代码复制问题:

<html> <head> <script type="text/javascript"> window.onload = function () { var buttons = document.getElementsByTagName('a'); for (var i=0; i<2; i++) { buttons[i].onclick = function () { alert(i); return false; } } } </script> </head> <body> <a href="">hi</a> <br /> <a href="">bye</a> </body> </html> 

点击链接时,我希望得到'0'和'1',但是我得到'2'。 为什么是这样?

顺便说一下,我设法通过使用“this”关键字来解决我的特定问题,但是我仍然对这种行为背后的问题感到好奇。

for循环中有一个非常常见的closures问题 。

闭包中的variables共享相同的单一环境,所以在执行onclickcallback时,循环已经运行, ivariables将指向最后一个条目。

你可以用一个函数工厂来解决这个问题:

 function makeOnClickCallback(i) { return function() { alert(i); return false; }; } var i; for (i = 0; i < 2; i++) { buttons[i].onclick = makeOnClickCallback(i); } 

如果你不熟悉闭包的工作方式,这可能是一个相当棘手的话题。 您可以查看下面的Mozilla文章进行简要介绍:

  • 使用闭包

注意:我也build议不要在for循环中使用var ,因为这可能欺骗你相信ivariables具有块范围,而另一方面, ivariables就像函数中的buttonsvariables一样。

您需要存储ivariables的状态,因为在事件触发时, i的作用域状态已增加到最大循环数。

 window.onload = function () { var buttons = document.getElementsByTagName('a'); for (var i=0; i<2; i++) { (function (i) { buttons[i].onclick = function () { alert(i); return false; } })(i); } } 

上面的例子创build了一个带有单个参数i的匿名函数,然后i其作为parameter passing。 这将在一个单独的作用域中创build一个新variables,并保存该特定迭代时的值。

这是一个执行问题的顺序

如何分配事件callback在javascript(jQuery)迭代数组

基本上,点击处理程序在循环退出后访问i ,因此i等于2