Обработчик JavaScript JavaScript не работает, как ожидалось, внутри цикла for

Я пытаюсь изучить JS и получить проблему.

Я пробовал много вещей и искал, но все напрасно. Следующий фрагмент кода работает не так, как ожидалось. Я должен получить значение я при щелчке, но он всегда возвращает 6. Я вытаскиваю свои волосы., Пожалуйста, помогите.

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

    console.log(i);

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

jsfiddle

Ответ 1

Рабочая DEMO

Это классическая проблема с закрытием JavaScript. Ссылка на объект i хранится в закрытии обработчика кликов, а не на фактическом значении i.

Каждый обработчик одного клика будет ссылаться на один и тот же объект, потому что существует только один объект-счетчик, который содержит 6, поэтому вы получаете по шесть на каждый клик.

Обходным путем является обернуть это в анонимную функцию и передать я в качестве аргумента. Примитивы копируются по значению в вызове функций.

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

UPDATE

Обновлен DEMO

Или вы можете использовать 'let' вместо var, чтобы объявить i. let дает вам новое связывание каждый раз. Его можно использовать только в ECMAScript 6 strict mode.

'use strict';

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

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

Ответ 2

Проблема заключается в том, что при повторении цикла через 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/

Ответ 3

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

Это потому, что он использует значение i как замыкание. i запоминается через замыкание, которое увеличивается на каждом этапе петли.

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