JavaScript: закрытие цикла? - PullRequest
       11

JavaScript: закрытие цикла?

5 голосов
/ 05 апреля 2011

Я хотел бы сделать что-то по следующему:

for (var i = 0; i < 10; ++i) {
    createButton(x, y, function() { alert("button " + i + " pressed"); }
}

Проблема в том, что я всегда получаю конечное значение i, потому что закрытие Javascript не является побочным значением.
Так как я могу сделать это с помощью JavaScript?

Ответы [ 5 ]

7 голосов
/ 05 апреля 2011

Одним из решений, если вы программируете для браузера, использующего JavaScript 1.7 или выше, является использование ключевого слова let:

for(var i = 0; i < 10; ++i) {
    let index = i;
    createButton(x, y, function() { alert("button " + index + " pressed"); }
}

Из Центра документации MDC:

Ключевое слово let вызывает создание переменной item с областью действия уровня блока, в результате чего создается новая ссылка для каждой итерации цикла for.Это означает, что для каждого закрытия создается отдельная переменная, что решает проблему, вызванную общей средой.

Проверьте MDC Doc Center для традиционного подхода (создание другого закрытия).

6 голосов
/ 05 апреля 2011
for(var i = 0; i < 10; i++) {
    (function(i) {
        createButton(function() { alert("button " + i + " pressed"); });
    })(i);
}

Обратите внимание, что JSLint не нравится этот шаблон. Выдает «Не создавать функции в цикле».

Живая демоверсия: http://jsfiddle.net/simevidas/ZKeXX/

4 голосов
/ 05 апреля 2011

Создайте новую область для закрытия, выполнив другую функцию:

for(var i = 0; i < 10; ++i) {
    createButton(x,y, function(value) { return function() { alert(...); }; }(i));
}

http://www.mennovanslooten.nl/blog/post/62

1 голос
/ 05 апреля 2011

Вы должны поместить замыкание в отдельную функцию.

for(var dontUse = 0; dontUse < 10; ++dontUse) {
    (function(i) {
        createButton(x, y, function() { alert("button " + i + " pressed"); }
    })(dontUse);
}

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

Это эквивалентно

function createIndexedButton(i) {
    createButton(x, y, function() { alert("button " + i + " pressed"); }
}

for(var i = 0; i < 10; ++i) {
    createIndexedButton(i);
}
0 голосов
/ 05 апреля 2011
for(var i = 0; i < 10; ++i) {
    createButton(x, y, (function(n) {
        return function() {
            alert("button " + n + " pressed");
        }
    }(i));
}

Внешняя анонимная функция вызывается автоматически и создает новое замыкание с n в области видимости, где оно принимает , а затем текущее значение i при каждом вызове.

...