循环索引奇异性的JavaScript
我对JS比较陌生,所以这可能是一个常见的问题,但在处理for循环和onclick函数时,我注意到了一些奇怪的事情。我能够用以下代码复制问题:循环索引奇异性的JavaScript,javascript,for-loop,onclick,Javascript,For Loop,Onclick,我对JS比较陌生,所以这可能是一个常见的问题,但在处理for循环和onclick函数时,我注意到了一些奇怪的事情。我能够用以下代码复制问题: <html> <head> <script type="text/javascript"> window.onload = function () { var buttons = document.getElementsByTagName('a'); for (var i=0; i<2; i++)
<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>
window.onload=函数(){
var buttons=document.getElementsByTagName('a');
对于(var i=0;i而言,这是一个执行顺序问题
基本上,单击处理程序在循环退出后很好地访问i
,因此i
等于2
,您需要存储i
变量的状态,因为在事件触发时,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);
}
}
window.onload=函数(){
var buttons=document.getElementsByTagName('a');
for(var i=0;i您在for
循环中拥有
封闭在一个闭包中的变量共享同一个环境,因此在执行onclick
回调时,循环已经运行,并且i
变量将指向最后一个条目
您可以使用函数工厂使用更多闭包来解决此问题:
function makeOnClickCallback(i) {
return function() {
alert(i);
return false;
};
}
var i;
for (i = 0; i < 2; i++) {
buttons[i].onclick = makeOnClickCallback(i);
}
函数makeOnClickCallback(i){
返回函数(){
警报(一);
返回false;
};
}
var i;
对于(i=0;i<2;i++){
按钮[i].onclick=makeOnClickCallback(i);
}
如果您不熟悉闭包的工作原理,这可能是一个相当棘手的话题。您可以查看以下Mozilla文章以获得简要介绍:
注意:我还建议不要在for
循环中使用var
,因为这可能会欺骗您相信I
变量具有块作用域,而另一方面I
变量就像按钮
变量一样,作用域在函数中。这也是一个作用域问题,I
在不太明显的情况下仍然存在。对,这就是为什么我链接到我的一篇关于闭包的帖子。在循环中创建函数不是recommended@Ryan:我不确定这是迂腐还是混乱。你在重复JSLint/JSHint警告,却没有花时间理解它的含义。请查看不应在循环中创建函数的示例。IIFE是可接受的,因为在let
得到普遍支持之前,它几乎是某些场景中的唯一选项。可接受的答案也会在循环中创建函数,但没有否决票或注释?好的,让我澄清一下:您在循环中创建了两个函数。t在一个循环中创建一个函数:点击处理程序。因此,被接受的答案最小化了效率低下,而你的效率最大化了。”瑞安:那么你是迂腐的,因为你在一个微优化上投票失败了,甚至没有一个真正的优化,因为它没有考虑C。ompiler自己的优化。在Chrome的控制台中,iLife在100万次操作中以大约100毫秒的速度出现(我鼓励您检查一下)这一点都不重要,因为这个问题从i
=0
循环到2
,所以差别是无法估量的。恭喜你,你是交通官,因为这家伙在车票过期1秒钟后回到车里,你就给了他停车罚款。:叹气:是的,我想我太迂腐了。所以起诉我吧。带上你的性能、编译器和你的“我是对的,我有126k代表”,在你完美的小世界里尽情跳跃,拥有你想要的一切。请举例说明你是如何用“这”解决问题的