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共享相同的单一环境,所以在执行onclick
callback时,循环已经运行, i
variables将指向最后一个条目。
你可以用一个函数工厂来解决这个问题:
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
,因为这可能欺骗你相信i
variables具有块范围,而另一方面, i
variables就像函数中的buttons
variables一样。
您需要存储i
variables的状态,因为在事件触发时, 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
。