fechamento javascript avaliação imediata [duplicado]
-
06-07-2019 - |
Pergunta
Esta questão já tem uma resposta aqui:
Considere o seguinte código 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]();
}
};
Os alertas imprimir '3' todas as três vezes. Eu quero um comportamento diferente - em cada iteração do loop gerar uma função que imprime o valor atual do i. Ou seja, 3 funções que imprimem índices diferentes.
Todas as idéias?
Solução
Criar uma função anônima que aceita i
como um parâmetro e retorno que determinada função:
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]();
}
Ou fazer algo semelhante: criar uma função anônima que aceita i
como um parâmetro para adicionar a função para a matriz:
for (var i = 0; i < 3; i++) {
(function(i) {
a.push(function() {
alert(i);
});
})(i);
}
for (var j = 0; j < 3; j++) {
a[j]();
}
Outras dicas
Apenas uma outra abordagem, usando currying :
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)));
};
};
Verifique o trecho acima correndo aqui .
var iterate = (function () {
var i, j = [];
for (i = 0; i < 3; i += 1) {
j.push(i);
alert(j[j.length - 1]);
}
}());
Você não precisa fechamento meramente saída um valor. Seu código deve, no entanto, estar contido em uma função de contenção orientada a objetos. Funções não tem que ser chamado para ser executado.
Você pode colocar o corpo de seu loop em uma função anônima:
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]();
}
Ao criar essa função e passando o valor do ciclo de "i" como o argumento, estamos criando um novo "i" variável no interior do corpo do laço que, essencialmente, esconde o exterior "i". O fecho de empurrar para a matriz agora vê a nova variável, cujo valor é definido quando a função função exterior é chamado no primeiro ciclo. Isso pode ser mais clara se usar um nome diferente quando criamos a nova variável ... Este faz a mesma coisa:
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]();
}
O valor de "iNew" é atribuído 0, 1, então 2, porque a função é chamada imediatamente pelo loop.
função (i) {alert (i)