JavaScript点击处理程序在for循环中没有按预期工作

我正在学习JS,遇到了一个问题。

我尝试了很多东西,谷歌了一下,但都是徒劳的。下面这段代码不能正常工作。我应该在点击时获得i的值,但它总是返回6。我在扯我的头发;请帮助。

for (var i = 1; i < 6; i++) {


console.log(i);


$("#div" + i).click(
function() {
alert(i);
}
);
}

jsfiddle

5554 次浏览

Working DEMO

这是一个经典的JavaScript闭包问题。对i对象的引用存储在单击处理程序闭包中,而不是i的实际值。

每一次点击处理程序都会引用相同的对象,因为只有一个持有6个的counter对象,所以每次点击你都会得到6个。

解决方法是将它包装在一个匿名函数中,并将i作为参数传递。原语在函数调用中按值复制。

for(var i=1; i<6; i++) {
(function (i) {
$("#div" + i).click(
function () { alert(i); }
);
})(i);
}

更新

更新后的DEMO .

或者你可以用“让”代替var来声明ilet每次都会给你新的绑定。只能在ECMAScript 6 strict mode中使用。

'use strict';


for(let i=1; i<6; i++) {


$("#div" + i).click(
function () { alert(i); }
);
}
$("#div" + i).click(
function() {
alert(i);
}
);

这是因为它使用i的值作为闭包。i通过一个闭包被记住,闭包在foor循环的每个阶段都增加。

$("#div" + i).click(function(event) {
alert($(event.target).attr("id").replace(/div/g, ""));
});

问题是,当你遍历循环时,i会增加。结果是6。当你说alert(i)时,你是在要求javascript告诉你i的值是在点击链接时,在这一点上是6。

如果你想获取盒子的内容,你可以这样做:

for (var i = 1; i < 6; i++) {
console.log(i);
$("#div" + i).click(function(e) {
alert($(this).text());
});
}
div {
display: inline-block;
width: 15px;
height: 15px;
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>