请看下面的代码:
<a href="javascript:void(-1)" id="a1">a1</a>
<a href="javascript:void(-1)" id="a2">a2</a>
<script type="text/javascript">
var buttons = []
buttons.push("a1")
buttons.push("a2")
var actions = []
for (var i in buttons)
{
actions[buttons[i]] = function() { alert(i) }
}
var elements = document.getElementsByTagName("a")
for (var k = 0; k < elements.length; k++)
{
elements[k].onclick = actions[elements[k].id]
}
</script>
基本上,它显示了两个锚点,a1和a2,我希望在点击相应的锚点时看到“1”和“2”弹出警报。但这并没有发生,我点击其中任何一个都得到了“2”。在花了一个小时思考代码后,我认为这可能是因为两个锚点的动态onclick
方法都保留了最后一个值“i”,所以我将该循环更改为:
for (var i in buttons)
{
var local_i = i.toString()
actions[buttons[i]] = function() { alert(local_i) }
}
希望每个动态函数都能得到它自己的带有立即值的“i”的副本。但是在这个改变之后,当我点击任何一个链接时,我都会弹出“1”。
我做错了什么?这对我来说是个巨大的阻碍。
3条答案
按热度按时间ltskdhd11#
最后一个值被存储,你可以使用闭包:
这个解决方案将
i
绑定到函数作用域,关键的技巧是在循环中执行函数,否则,您将得到迭代并警告i
的最后一个值的最终结果。参考:http://www.jibbering.com/faq/faq_notes/closures.html
nlejzf6q2#
这个blog post很好地解释了这个问题,问题是在JavaScript中循环没有自己的变量作用域,所以内部函数使用父函数的作用域。
knsnq2tg3#
不要用
for (… in …)
来表示数组,而是使用简单的for
循环: