Вопрос

На этот вопрос уже есть ответ здесь:

Рассмотрим следующий код Javascript:

var a = [];

var f = function() {

    for (var i = 0; i < 3; i++) {
        a.push(function(){alert(i)});
    }
    for (var j = 0; j < 3; j++) {
        a[j]();
    }
};

Предупреждения выводят '3' все три раза.Я хочу другого поведения - на каждой итерации цикла генерировать функцию, которая выводит текущее значение i.То есть.3 функции, которые печатают разные индексы.

Есть какие-нибудь идеи?

Это было полезно?

Решение

Создайте анонимную функцию, которая принимает i в качестве параметра и возвращает эту определенную функцию:

for (var i = 0; i < 3; i++) {
    a.push((function(i) {
        return function() {
            alert(i);
        }
    })(i));
}

for (var j = 0; j < 3; j++) {
    a[j]();
}

Или сделайте что-то подобное:создайте анонимную функцию, которая принимает i в качестве параметра для добавления функции в массив:

for (var i = 0; i < 3; i++) {
    (function(i) {
        a.push(function() {
            alert(i);
        });
    })(i);
}

for (var j = 0; j < 3; j++) {
    a[j]();
}

Другие советы

Просто другой подход, использующий приготовление карри:

var a = [];
var f = function() {
    for (var i = 0; i < 3; i++) {
        a.push((function(a){alert(a);}).curry(i));
    }
    for (var j = 0; j < 3; j++) {
        a[j]();
    }
};

// curry implementation
Function.prototype.curry = function() {
  var fn = this, args = Array.prototype.slice.call(arguments);
  return function() {
    return fn.apply(this, args.concat(
      Array.prototype.slice.call(arguments)));
  };
};

Проверьте приведенный выше фрагмент запущенного здесь.

var iterate = (function () {
    var i, j = [];
    for (i = 0; i < 3; i += 1) {
        j.push(i);
        alert(j[j.length - 1]);
    }
}());

Вам не нужно замыкание, чтобы просто вывести значение.Однако ваш код должен содержаться в функции для объектно-ориентированного удержания.Функции не обязательно вызывать для выполнения.

Вы можете поместить тело вашего цикла в анонимную функцию:

var a = [];

for(var i = 0; i < 3; i++) (function(i) {
    a.push(function() { alert(i); });
})(i)

for(var j = 0; j < 3; j++) {
    a[j]();
}

Создавая эту функцию и передавая значение цикла "i" в качестве аргумента, мы создаем новую переменную "i" внутри тела цикла, которая по существу скрывает внешнее "i".Замыкание, которое вы помещаете в массив, теперь видит новую переменную, значение которой устанавливается при вызове функции outer function в первом цикле.Это могло бы быть понятнее, если бы мы использовали другое имя при создании новой переменной...Это делает то же самое:

var a = [];

for(var i = 0; i < 3; i++) (function(iNew) {
    a.push(function() { alert(iNew); });
})(i)

for(var j = 0; j < 3; j++) {
    a[j]();
}

Значению "iNew" присваивается 0, затем 1, затем 2, потому что функция вызывается циклом немедленно.

функция (i){оповещение(i)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top