Pergunta

Alguém pode me explicar (de forma clara e concisa) por que esse código funciona dessa maneira?Eu venho de uma experiência fortemente tipada em Java (6 e 7), onde os fechamentos não existem e não funcionam da maneira que funcionam em javascript.Acho que os conceitos relacionados a esta questão são:fechamentos e cadeia de escopo.

Aqui está o exemplo:

var myfuncs = function() {
    var funcs = []
    var i;
    for (i = 0; i < 10; i++) {
       funcs[i] = function() { console.log(i); }
    }
    return funcs;
}

var allfuncs = myfuncs();
allfuncs.forEach(function(fn) { fn(); });

O exemplo acima registra 9 (10 vezes), mas a expectativa e minha própria intuição pensavam que registraria 0-9.

Por que isso funciona dessa maneira em Javascript?Os fechamentos são muito poderosos, mas estou tentando entender o conceito de uma vez por todas!Um exemplo ligeiramente modificado produz a saída correta, mas por quê?

var myfuncs = function() {
    var funcs = []
    var i;
    for (i = 0; i < 10; i++) {
       funcs[i] = (function(index) { console.log(index); })(i);
    }
    return funcs;
}

var allfuncs = myfuncs();
allfuncs.forEach(function(fn) { fn(); }); 

Os encerramentos não são exclusivos do Javascript, mas quero ver por que eles são poderosos no contexto de quando o javascript é realmente escrito para interagir com o navegador/dom.

Alguém tem exemplos bons e práticos de como podemos aplicar a técnica de fechamento na interface com o navegador/dom?

Obrigado.

Foi útil?

Solução

Nos exemplos que você tem, é muito simples.

No seu primeiro exemplo, há apenas uma variável i e tudo faz referência a esse valor único.Então..ele imprime o número 9 dez vezes.Cada função capturou um compartilhado valor de i isso muda.

No segundo exemplo você está usando um encerramento.Cada função possui uma variável privada chamada index que recebe - e aqui está a parte importante - um cópia de do valor i.

Então, você consegue 0 através 9 porque são dez funções, cada uma com uma particularidade index variável e cada um desses index variáveis ​​obtêm um instantâneo de i como existia na época.

Esta forma mais longa de fechamento pode ajudar:

function myFactory(index) {
  return function() {
    console.log(index);
  }
}

var myfuncs = function() {
    var funcs = []
    var i;
    for (i = 0; i < 10; i++) {
       funcs[i] = myFactory(i);
    }
    return funcs;
}

var allfuncs = myfuncs();
allfuncs.forEach(function(fn) { fn(); }); 
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top