有两个版本,据说当用户点击第一个链接时,它会提醒“1”,第二个链接,“2”等:
版本1:
<a href="#" id="link1">click me</a>
<a href="#" id="link2">click me</a>
<a href="#" id="link3">click me</a>
<a href="#" id="link4">click me</a>
<a href="#" id="link5">click me</a>
<script type="text/javascript">
for (i = 1; i <= 5; i++) {
document.getElementById('link' + i).onclick = (function() {
return function() {
var n = i;
alert(n);
return false;
}
})();
}
</script>
第2版:
<a href="#" id="link1">click me</a>
<a href="#" id="link2">click me</a>
<a href="#" id="link3">click me</a>
<a href="#" id="link4">click me</a>
<a href="#" id="link5">click me</a>
<script type="text/javascript">
for (i = 1; i <= 5; i++) {
document.getElementById('link' + i).onclick = (function() {
var n = i;
return function() {
alert(n);
return false;
}
})();
}
</script>
版本1不起作用。版本2将。我想我知道原因,但是想与其他人的解释比较,为什么版本1不起作用。
答案 0 :(得分:4)
版本1不起作用,因为共享变量“i”(在这种情况下为全局变量,因为您忘记了var
)通过循环创建的每个“click”处理函数。
在第二个版本中,您使用小包装函数创建一个新的词法范围。这给了每个“点击”处理程序它是非常私有的“我”。
答案 1 :(得分:3)
在第二个示例中,您创建了一个var n = i;
,它使i
值作用于onclick函数。在第一个时,onclick函数仍然使用全局值i
我建议改用这个用法:
for (i = 1; i <= 5; i++) {
document.getElementById('link' + i).onclick = (function(i) {
return function() {
alert(i);
return false;
}
})(i);
}
在这种情况下,您将获得相同的行为,因为i
将是onclick函数的局部变量,因为它是一个参数。
答案 2 :(得分:0)
首先不起作用,因为:我是每个闭包的一部分。经过5次迭代后,由于后缀增量运算符,我才6。每次调用事件处理程序时,它都会从其闭包范围获取i的值,该范围始终为6。
第二部分有效:因为每个闭包都在n中复制i,n是每个闭包的一部分。