258

我正在尝试学习 JS,但遇到了问题。

我尝试了很多东西并用谷歌搜索,但都是徒劳的。以下代码无法按预期工作。i我应该在点击时获得价值,但它总是返回 6。请帮忙。

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

    console.log(i);

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

jsfiddle

4

3 回答 3

153

工作演示

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

每个单击处理程序都将引用同一个对象,因为只有一个计数器对象可以容纳 6 个,因此每次单击都会得到 6 个。

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

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

更新

更新了演示

或者您可以使用'let'var声明i. let每次都为您提供新鲜的装订。它只能在 ECMAScript 6 中使用strict mode

'use strict';

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

        $("#div" + i).click(
            function () { alert(i); }
        );
 }
于 2013-05-16T14:15:09.037 回答
39

问题是,当您遍历循环时,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>

于 2013-05-16T14:17:47.120 回答
18
$("#div" + i).click(
    function() {
        alert(i);
    }
);

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

$("#div" + i).click(function(event) {
    alert($(event.target).attr("id").replace(/div/g, ""));
});
于 2013-05-16T14:15:55.557 回答