Fechamentos de JavaScript
As variáveis JavaScript podem pertencer ao escopo local ou global .
Variáveis globais podem se tornar locais (privadas) com closures .
Variáveis globais
A function
pode acessar todas as variáveis definidas dentro da função, assim:
Exemplo
function myFunction() {
let a = 4;
return a * a;
}
Mas a function
também pode acessar variáveis definidas fora da função, assim:
Exemplo
let a = 4;
function myFunction() {
return a * a;
}
No último exemplo, a é uma variável global .
Em uma página da Web, as variáveis globais pertencem ao objeto window.
As variáveis globais podem ser usadas (e alteradas) por todos os scripts na página (e na janela).
No primeiro exemplo, a é uma variável local .
Uma variável local só pode ser usada dentro da função onde está definida. Ele está oculto de outras funções e outros códigos de script.
Variáveis globais e locais com o mesmo nome são variáveis diferentes. Modificar um, não modifica o outro.
Variáveis criadas sem uma palavra-chave de declaração ( var
,
let
, ou const
) são sempre globais, mesmo que sejam criadas dentro de uma função.
Exemplo
function myFunction() {
a = 4;
}
Vida útil variável
As variáveis globais permanecem vivas até que a página seja descartada, como quando você navega para outra página ou fecha a janela.
Variáveis locais têm vida curta. Eles são criados quando a função é invocada e excluídos quando a função é concluída.
Um Contra-Dilema
Suponha que você queira usar uma variável para contar algo e queira que esse contador esteja disponível para todas as funções.
Você pode usar uma variável global e a function
para aumentar o contador:
Exemplo
// Initiate counter
let counter = 0;
// Function to increment
counter
function add() {
counter += 1;
}
// Call add() 3 times
add();
add();
add();
// The counter should now be 3
Há um problema com a solução acima: qualquer código na página pode alterar o contador, sem chamar add().
O contador deve ser local para a add()
função, para evitar que outro código o altere:
Exemplo
// Initiate counter
let counter = 0;
// Function to increment
counter
function add() {
let counter = 0;
counter += 1;
}
//
Call add() 3 times
add();
add();
add();
//The counter should
now be 3. But it is 0
Não funcionou porque exibimos o contador global em vez do contador local.
Podemos remover o contador global e acessar o contador local deixando a função retorná-lo:
Exemplo
// Function to increment
counter
function add() {
let counter = 0;
counter += 1;
return counter;
}
//
Call add() 3 times
add();
add();
add();
//The counter should
now be 3. But it is 1.
Não funcionou porque redefinimos o contador local toda vez que chamamos a função.
Uma função interna JavaScript pode resolver isso.
Funções aninhadas de JavaScript
Todas as funções têm acesso ao escopo global.
De fato, em JavaScript, todas as funções têm acesso ao escopo "acima" delas.
JavaScript suporta funções aninhadas. As funções aninhadas têm acesso ao escopo "acima" delas.
Neste exemplo, a função interna plus()
tem acesso à counter
variável na função pai:
Exemplo
function add() {
let counter = 0;
function plus() {counter += 1;}
plus();
return counter;
}
Isso poderia ter resolvido o contra-dilema, se pudéssemos alcançar a plus()
função de fora.
Também precisamos encontrar uma maneira de executar counter = 0
apenas uma vez.
Precisamos de um encerramento.
Fechamentos de JavaScript
Lembre-se de funções de auto-invocação? O que essa função faz?
Exemplo
const add = (function () {
let counter = 0;
return function () {counter += 1; return counter}
})();
add();
add();
add();
// the counter is now 3
Exemplo explicado
A variável add
é atribuída ao valor de retorno de uma função de auto-invocação.
A função de auto-invocação é executada apenas uma vez. Ele define o contador como zero (0) e retorna uma expressão de função.
Desta forma add se torna uma função. A parte "maravilhosa" é que ele pode acessar o contador no escopo pai.
Isso é chamado de encerramento de JavaScript . Torna possível que uma função tenha variáveis " privadas ".
O contador é protegido pelo escopo da função anônima e só pode ser alterado usando a função add.
Um encerramento é uma função que tem acesso ao escopo pai, mesmo após o fechamento da função pai.