Подтвердить что ты не робот

Привязка переменных JavaScript и цикл

Рассмотрим такой цикл:

for(var it = 0; it < 2; it++)
{
    setTimeout(function() {
        alert(it);
    }, 1);
}

Вывод:

=> 2
=> 2

Мне бы хотелось: 0, 1. Я вижу два способа исправить это:

Решение № 1.

Это основано на том, что мы можем передавать данные в setTimeout.

for(var it = 0; it < 2; it++)
{
    setTimeout(function(data) {
        alert(data);
    }, 1, it);
}

Решение № 2.

function foo(data)
{
    setTimeout(function() {
        alert(data);
    }, 1);
}

for(var it = 0; it < 2; it++)
{
    foo(it);
}

Есть ли другие альтернативы?

4b9b3361

Ответ 1

На самом деле не больше, чем два способа, которые вы предложили, но здесь другой

for(var it = 0; it < 2; it++)
{
    (function() {
        var m = it;   
        setTimeout(function() {
            alert(m);
        }, 1);
    })(); 
}

По существу, вам нужно зафиксировать значение переменной в закрытии. Этот метод использует сразу вызываемую анонимную функцию для захвата значения внешней переменной it в локальной переменной m.

Здесь Рабочий демонстрационный пример. добавьте /edit в URL-адрес, чтобы увидеть код

Ответ 2

С ключевым словом let вы можете обойти это полностью:

for(let it = 0; it < 2; it++)
{
    setTimeout(function() {
        alert(it);
    }, 1);
}

Ответ 3

Подобно описанному выше решению, но сам вызывающий внутри функции setTimeout

for(var it = 0; it < 2; it++)
{
    setTimeout(function(cur) {
        return function(){
           alert(cur);
        };
     }(it), 1);
 }

Ответ 4

Подобно другим решениям, но, по-моему, чище:

for (var it = 0; it < 2; it++) {
  // Capture the value of "it" for closure use
  (function(it) {
     setTimeout(function() {
       alert(it);
     }, 1);
  // End variable captured code
  })(it)
}

Это сохраняет одно и то же имя переменной для захвата и делает это для всего цикла, отделяя это от логики настройки таймаута. Если вы хотите добавить больше логики внутри блока, вы можете это сделать тривиально.

Единственное, что мне не нравится в решении, это повторение "it" в конце.