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?

Foi útil?

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)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top