此问题取自此处接受的答案中的第一个问题:https://stackoverflow.com/questions/1684917/what-questions-should-a-javascript-programmer-be-able-to-answer
<a href="#">text</a><br><a href="#">link</a>
<script>
var as = document.getElementsByTagName('a');
for ( var i = as.length; i--; ) {
as[i].onclick = function() {
alert(i);
return false;
}
}
</script>
为什么锚点在点击时会在循环内警告-1而不是各自的计数器?如何修复代码,以便提醒正确的数字? (提示:关闭)
答案 0 :(得分:4)
当onclick
触发i
的值为-1
时(因为这是i
将获得的最后一个值)。
解决方案是创建一个闭包,将迭代的那个i
的值绑定到onclick-listener。
解决这个问题的一种可能方法是:
for ( var i = as.length; i--; ) {
as[i].onclick = (function(actually_i) {
return function () {
alert(actually_i);
return false;
}
}(i)) // pass in i
}
此代码还有其他问题。我就是这样写的:
for (var i; i < as.length; i += 1) {
as[i].addEventListener("click", (function(actually_i) {
return function (event) {
event.preventDefault();
alert(actually_i);
}
}(i)) // pass in i
}
i--
构建过于聪明并导致错误addEventListener
而不是分配onclick
(模块化问题)。return false
同时做到并且总是错误的。答案 1 :(得分:2)
当前情况:
i = 1
):设置点击第一个链接。i = 0
):设置点击第二个链接。i
等于-1
。i
仍然等于-1
。使用IIFE可以创建一个全新的上下文,其中i
的值不再与i
无关。然后,考虑下面的示例,术语“closure”指的是j
与返回函数之间的关系,它将作为点击处理程序:
var as = document.getElementsByTagName('a');
for ( var i = as.length; i--; ) {
as[i].onclick = function (j) {
return function () {
alert(i + ' ' + j);
return false;
};
}(i);
}