немедленная оценка закрытия javascript [дубликат]
-
06-07-2019 - |
Вопрос
На этот вопрос уже есть ответ здесь:
Рассмотрим следующий код 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)