Um dos recursos mais importantes do JavaScript é o uso de fechamentos. Devido ao uso de fechamentos, o escopo atual pode sempre acessar escopos externos. Como o JavaScript não possui escopo no nível do bloco e apenas o escopo da função, o uso de fechamentos está intimamente relacionado às funções.
Simular variáveis privadas
A cópia do código é a seguinte:
contador de funções (start) {
var count = start;
retornar {
incremento: function () {
contagem ++;
},
get: function () {
contagem de retorno;
}
}
}
var foo = contador (4);
foo.Increment ();
foo.get (); // 5
Aqui, o contador retorna dois fechamentos: incremento da função e obtenha. Essas duas funções mantêm o acesso ao cotonete, para que possam acessar a contagem de variáveis definida no escopo da contagem.
Mecanismo de trabalho de variáveis privadas
Como o JavaScript não pode atribuir valores e referências a escopos, no exemplo acima, não há como acessar diretamente a contagem interna de variável privada de fora. A única maneira é acessá -lo definindo o fechamento.
A cópia do código é a seguinte:
var foo = novo contador (4);
foo.hack = function () {
contagem = 1337;
};
O código acima não altera o valor da variável de contagem no escopo do contador, porque o hack não é definido no contador. O código acima criará ou substituirá apenas a contagem global de variáveis.
Fechamentos no loop
Um dos erros mais fáceis é usar o fechamento dentro de um loop.
A cópia do código é a seguinte:
for (var i = 0; i <10; i ++) {
setTimeout (function () {
console.log (i);
}, 1000);
}
O código acima não será lançado de 0 a 9, mas será lançado 10 vezes continuamente.
O anonimato acima manterá uma referência à variável i. Quando a função do console.log é chamada para iniciar a saída, este é o loop que terminou e a variável I já é 10.
Para evitar o erro acima, precisamos criar uma cópia da variável i valor cada vez que fizemos um loop.
Evite erros de cotação
Para copiar o valor de uma variável no loop, a melhor maneira é adicionar uma função anônima à camada externa e executá -la imediatamente.
A cópia do código é a seguinte:
for (var i = 0; i <10; i ++) {
(função (e) {
setTimeout (function () {
console.log (e);
}, 1000);
})(eu);
}
Essa função anônima externa toma a variável de loop i como o primeiro parâmetro e copia seu valor para seu próprio parâmetro e.
A função anônima externa passa o parâmetro e para o setTimeout, portanto, o setTimeout tem uma referência ao parâmetro e. Além disso, o valor desse parâmetro E não será alterado devido a alterações de loop externo.
Há outra maneira de alcançar o mesmo efeito, que é retornar uma função anônima na função anônima no setTimeout:
A cópia do código é a seguinte:
for (var i = 0; i <10; i ++) {
setTimeout ((function (e) {
Return function () {
console.log (e);
}
}) (i), 1000)
}
Além disso, também pode ser alcançado através do método de ligação.
A cópia do código é a seguinte:
for (var i = 0; i <10; i ++) {
setTimeout (console.log.bind (console, i), 1000);
}
No final do artigo, vamos resumir:
(1) O fechamento é um princípio de design. Ele simplifica as chamadas do usuário analisando o contexto, permitindo ao usuário alcançar seu objetivo sem conhecê -lo;
(2) Os principais artigos on -line sobre análise de fechamentos são realmente contrários ao princípio de fechamento. Se você precisar conhecer os detalhes do fechamento para ser bem usado, esse fechamento é uma falha de design;
(3) Tente aprender o mínimo possível.