Variáveis JavaScript podem pertencer ao grupo local ou Escopo global.
Variáveis globais podem se tornar locais (privadas) com fechamentos.
Uma função
pode acessar todas as variáveis definidas dentro da função, assim:
function myFunction() {
let a = 4;
return a * a;
}
Experimente você mesmo →
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Functions</h2>
<p>A function can access variables defined inside the function:</p>
<p id="demo"></p>
<script>
myFunction();
function myFunction() {
let a = 4;
document.getElementById("demo").innerHTML = a * a;
}
</script>
</body>
</html>
Mas uma função
também pode acessar variáveis definidas fora da função, assim:
let a = 4;
function myFunction() {
return a * a;
}
Experimente você mesmo →
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Functions</h2>
<p>A function can access variables defined outside the function:</p>
<p id="demo"></p>
<script>
let a = 4;
myFunction();
function myFunction() {
document.getElementById("demo").innerHTML = a * a;
}
</script>
</body>
</html>
No último exemplo, a é um valor global variável.
Em uma página web, as variáveis globais pertencem à página.
Variáveis globais podem ser usadas (e alteradas) por todos os outros scripts na página.
No primeiro exemplo, a é um local variável.
Uma variável local só pode ser usada dentro da função onde está definida. Isto está oculto de outras funções e outros códigos de script.
Global e variáveis 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 criados dentro de uma função.
function myFunction() {
a = 4;
}
Experimente você mesmo →
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Functions</h2>
<p>Variables created without a declaration keyword (var, let, or const) are always global,
even if they are created inside a function.:</p>
<p id="demo"></p>
<script>
myFunction();
document.getElementById("demo").innerHTML = a * a;
function myFunction() {
a = 4;
}
</script>
</body>
</html>
Variáveis globais permanecem vivas até que a página seja descartada, como quando você navega para outra página ou feche a janela.
Local variáveis têm vidas curtas. Eles são criados quando a função é invocado e excluído quando a função for concluída.
Suponha que você queira usar uma variável para contar algo e queira isso contador esteja disponível para todas as funções.
Você poderia usar uma variável global e uma função
para aumentar o contador:
// 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
Experimente você mesmo →
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Function Closures</h2>
<p>Counting with a global variable.</p>
<p id="demo"></p>
<script>
// 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
document.getElementById("demo").innerHTML = "The counter is: " + counter;
</script>
</body>
</html>
Há um problema com a solução acima: Qualquer código na página pode alterar o contador, sem chamando add().
O contador deve ser local para a função add()
, para evitar que outro código seja alterado isto:
// 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
Experimente você mesmo →
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Function Closures</h2>
<p>Counting with a local variable.</p>
<p id="demo"></p>
<script>
// Initiate counter
let counter = 0;
// Function to increment counter
function add() {
let counter = 0;
counter += 1;
}
// Call add() 3 times
add();
add();
add();
// The result is not 3 because you mix up the globaland local counter
document.getElementById("demo").innerHTML = "The counter is: " + counter;
</script>
</body>
</html>
Não funcionou porque exibimos o contador global em vez do local contador.
Podemos remover o contador global e acessar o contador local deixando o função retorna:
// 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.
Experimente você mesmo →
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Closures</h2>
<p>Counting with a local variable.</p>
<button type="button" onclick="myFunction()">Count!</button>
<p id="demo">0</p>
<script>
// Function to increment counter
function add() {
let counter = 0;
counter += 1;
return counter;
}
// Trying to increment the counter
function myFunction(){
document.getElementById("demo").innerHTML = add();
}
</script>
</body>
</html>
Não funcionou porque zeramos o contador local toda vez que ligamos para o função.
Uma função interna JavaScript pode resolver isso.
Todas as funções têm acesso ao escopo global.
Na verdade, em JavaScript, todas as funções têm acesso ao escopo “acima” delas.
JavaScript oferece suporte a funções aninhadas. Funções aninhadas têm acesso ao escopo "acima" deles.
Neste exemplo, a função interna plus()
tem acesso para a variável counter
na função pai:
function add() {
let counter = 0;
function plus() {counter += 1;}
plus();
return counter;
}
Experimente você mesmo →
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Function Closures</h2>
<p>Counting with a local variable.</p>
<p id="demo">0</p>
<script>
document.getElementById("demo").innerHTML = add();
function add() {
let counter = 0;
function plus() {counter += 1;}
plus();
return counter;
}
</script>
</body>
</html>
Isso poderia ter resolvido o dilema do contador, se conseguíssemos chegar ao plus()
funcionar de fora.
Também precisamos encontrar uma maneira de executar counter=0
apenas uma vez.
Precisamos de um encerramento.
Lembra das funções de auto-invocação? O que essa função faz?
const add = (function () {
let counter = 0;
return function () {counter += 1; return counter}
})();
add();
add();
add();
// the counter is now 3
Experimente você mesmo →
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript Closures</h2>
<p>Counting with a local variable.</p>
<button type="button" onclick="myFunction()">Count!</button>
<p id="demo">0</p>
<script>
const add = (function () {
let counter = 0;
return function () {counter += 1; return counter;}
})();
function myFunction(){
document.getElementById("demo").innerHTML = add();
}
</script>
</body>
</html>
A variável add
é atribuída ao valor de retorno de uma chamada automática função.
A função de auto-invocação é executada apenas uma vez. Ele define o contador para 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 fechamento de JavaScript. Ele torna possível para uma função ter 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.