JavaScript单击处理程序在for循环中未按预期工作

时间:2013-05-16 14:13:39

标签: javascript javascript-events event-handling mouseevent

我正在尝试学习JS并遇到问题。

我尝试了许多东西并用谷歌搜索但都徒劳无功。下面的代码段不能按预期工作。我应该在点击时获得i的价值,但它总是会返回6.我正在拔头发。请帮忙。

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

    console.log(i);

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

jsfiddle

3 个答案:

答案 0 :(得分:113)

Working DEMO

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

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

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

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

<强>更新

Updated DEMO

或者您可以使用'let'代替var来声明ilet每次都会给你新的装订。它只能在ECMAScript 6 strict mode中使用。

'use strict';

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

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

答案 1 :(得分:28)

问题在于,当您遍历循环时,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());
    });
}

工作示例:http://jsfiddle.net/rmXcF/2/

答案 2 :(得分:12)

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

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

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