Для цикла в Javascript выводит значение только из последней итерации

У меня есть этот код Javascript, который работает как положено:




setTimeout(function(){$(".test").append("test1")},1000);
setTimeout(function(){$(".test").append("test2")},2000);


Это показывает "test1" сначала, а потомtest2" через секунду, как таковой: "test1test2"что я и хочу

Когда я пытаюсь сделать это в цикле FOR, вот так:

var timeInterval = 1000;
for (var i = 0, l = 2; i < l; i++ ) {
    setTimeout(function(){$(".test").append("test" + i)},timeInterval);
    timeInterval += 1000;
}

Тогда я получаюtest2" сначала, а потомtest2" через секунду, как таковой: "test2test2"что не то, что я хочу.

На самом деле, если l = 3, то получаюtest3test3test3" вместо "test1test2test3", Кто-нибудь знает, как решить эту проблему?

 Scott Selby25 окт. 2012 г., 23:51
Я думаю, потому что тайм-аут больше, чем скорость, через которую он проходит i, поэтому к тому времени, когда он оценивает i, он уже равен 3

Ответы на вопрос(5)

i всегда будет ссылаться на текущее значениеi (не значениеi когда звонили) в этой ситуации.

Тот'Как работает область в JavaScript.

Смотрите ответ @Esailija для решения.

вы можете использовать другую функцию для этого:

var timeInterval = 1000;
for (var i = 0, l = 2; i < l; i++) {
    setTimeout((function(i) {
        return function() {
            $(".test").append("test" + i);
        }
    })(i), timeInterval);
    timeInterval += 1000;
}
 Curt26 окт. 2012 г., 03:12
Спасибо Esailija. Это тоже сработало.

Это потому что ты нет захват значенияi из цикла. Вы можете настроить свой код так, чтобы он работал:

var timeInterval = 1000;
for (var i = 0, l = 2; i < l; i++ ) {
    (function(i2, timeInterval2) {
        setTimeout(function() {
            $(".test").append("test" + i2);
        }, timeInterval2);
    })(i, timeInterval);
    timeInterval += 1000;
}
 Curt26 окт. 2012 г., 03:14
Спасибо Кори за ваше предложение. Вам необходимо удалить один из закрывающих скобок из: timeInterval)); в timeInterval); и это работает.
 Cᴏʀʏ26 окт. 2012 г., 15:48
@ Курт: Хороший улов; отредактировано, переформатировано.

i в объеме решается в других ответах, но так как выПри использовании jQuery у вас есть другие варианты.

использование$.each вместоfor цикл, таким образом, у вас есть доступ кi переменная в любом месте в этой области.

использованиеdelay вместоsetTimeout, Чтобы это работало, вам нужно сначала запустить очередь:$(".test").show(0).delay(timeInterval).append("test" + i)

Решение Вопроса

i увеличивается до 2, когдаsetTimeout выполняет функцию, и поэтому он просто печатаетi значение как 2, приводящее к.test2test2

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

DEMO: http://jsfiddle.net/mBBJn/1/

var timeInterval = 1000;
for (var i = 0, l = 2; i < l; i++) {
    (function(i) {
        setTimeout(function() {
            $(".test").append("test" + (i+1))
        }, timeInterval);
        timeInterval += 1000;
    })(i);
}

Редактировать: используемые функции args.

 Curt26 окт. 2012 г., 03:10
Спасибо Вега. Это сработало!

Ваш ответ на вопрос