JavaScript: Escopo em JavaScript
Última atualização: 2026-10-13
O escopo determina onde uma variável pode ser acessada. Pense como um documento de identidade — seu RG só funciona dentro do seu estado, e sua habilitação não serve no exterior. Variáveis funcionam igual: quando você sai do escopo delas, ficam inacessíveis.
1. Tipos de Escopo e Suas Regras
Variáveis declaradas com var, let ou const no nível mais externo têm escopo global e podem ser acessadas de qualquer lugar.
<script>
var globalVar = "Sou uma variável global";
function test() {
console.log(globalVar); // Acessível
}
test();
</script>
Variáveis globais são práticas, mas podem facilmente poluir o namespace — conforme o projeto cresce, conflitos de nomes se tornam inevitáveis. Minimize o uso de variáveis globais.
(2) Escopo de Função
Variáveis declaradas com var seguem o escopo de função: só existem dentro da função atual e desaparecem fora dela.
<script>
function greet() {
var message = "Olá";
console.log(message); // Funciona
}
greet();
try {
console.log(message); // ReferenceError!
} catch(e) {
console.log("Falha no acesso: " + e.message);
}
</script>
Um erro clássico com o escopo de função do var: usar var em um loop for faz a variável "vazar" após o loop terminar.
(3) Escopo de Bloco
Variáveis declaradas com let e const seguem o escopo de bloco: só existem dentro do {} atual.
<script>
if (true) {
let x = 10;
const y = 20;
var z = 30;
console.log("Dentro do bloco: x=" + x + ", y=" + y + ", z=" + z);
}
console.log("Fora do bloco: z=" + z); // var não é restrita por blocos
try {
console.log(x); // x não é acessível aqui
} catch(e) {
console.log("x não acessível: " + e.message);
}
</script>
Por isso contadores de loop devem usar let em vez de var.
(4) Cadeia de Escopo
Escopos internos podem acessar variáveis de escopos externos — assim como você pode usar coisas de casa na escola (se tiver levado). Ao procurar uma variável, o JavaScript busca do escopo atual para fora, camada por camada, até chegar ao escopo global. Essa cadeia é chamada de cadeia de escopo.
<script>
const cidade = "São Paulo";
function externa() {
const bairro = "Pinheiros";
function interna() {
const rua = "Rua dos Pinheiros";
console.log(rua, bairro, cidade); // Tudo acessível
}
interna();
}
externa();
</script>
Escopos externos não podem acessar variáveis de escopos internos — assim como você não consegue enfiar a mão no bolso de um aluno de fora da sala de aula.
(5) Hoisting
Declarações com var são "elevadas" ao topo do escopo, mas as atribuições não:
<script>
console.log(a); // undefined (não é erro!)
var a = 5;
// Ordem real de execução: var a; → console.log(a); → a = 5;
</script>
let e const também sofrem hoisting, mas acessá-los antes da declaração lança um erro — essa região é chamada de Zona Morta Temporal (TDZ):
<script>
try {
console.log(b); // ReferenceError!
} catch(e) {
console.log("Zona morta temporal: " + e.message);
}
let b = 5;
</script>
Resumo: sempre use let e const; evite as armadilhas de hoisting do var.
(6) Closures Explicadas de Forma Intuitiva
Uma closure = uma função + o ambiente de variáveis onde ela nasceu. É como alguém que saiu da cidade natal, mas continua lembrando como era — mesmo que a cidade tenha mudado depois, a memória permanece a mesma.
<script>
function criarContador() {
let contagem = 0; // Esta variável fica "trancada" dentro da closure
return function() {
contagem++;
return contagem;
};
}
const contador = criarContador();
console.log(contador()); // 1
console.log(contador()); // 2
console.log(contador()); // 3
// A variável contagem não foi destruída porque a função retornada ainda "lembra" dela
</script>
criarContador já terminou de executar — logicamente, contagem deveria ser destruída. Mas a função retornada segura contagem com força, então ela sobrevive. Isso é uma closure.
(7) Casos Práticos de Uso de Closures
- Contadores: Registrar estado sem variáveis globais (como mostrado acima)
- Variáveis privadas: Variáveis dentro de closures não podem ser acessadas diretamente de fora — apenas pelas funções retornadas
- Funções de callback: Manter referências a variáveis em listeners de eventos e temporizadores
▶ Exemplo: var vs let em Loops
▶ Experimente▶ Exemplo: Demonstração da Cadeia de Escopo
▶ Experimente▶ Exemplo: Contador com Closure e Variáveis Privadas
▶ Experimente▶ Exemplo: Comparação de Hoisting
▶ Experimente❓ Perguntas Frequentes
var em um loop for faz todos os callbacks mostrarem o mesmo valor?var tem escopo de função — depois que o loop termina, existe apenas um i, e todos os callbacks compartilham ele (que já vale o valor final do loop). Com let, cada iteração recebe sua própria cópia independente de i.null à referência.let ou const?const por padrão; só use let quando precisar reatribuir. Esse hábito evita que você modifique acidentalmente variáveis que não deveriam mudar.📖 Resumo
- Escopo global é visível em todo lugar; escopo de função é limitado à função; escopo de bloco é limitado a
{} - A cadeia de escopo significa que escopos internos acessam variáveis externas, mas não o contrário
vartem escopo de função e hoisting;let/consttêm escopo de bloco e zona morta temporal- Closures permitem que funções "lembrem" seu escopo de criação, úteis para privacidade de dados
- Minimize variáveis globais encapsulando código em funções ou módulos
📝 Exercícios
- Escreva uma função
criarSaudacao(saudacao)que retorne uma função que, ao receber um nome, retornesaudacao + ", " + nome. Crie duas funções de saudação com saudações diferentes e verifique que não interferem uma na outra. - Escreva uma função
criarCarteira(saldoInicial)que retorne três métodos:depositar,sacareobterSaldo. Osaldonão deve ser acessível diretamente de fora (variável privada) — só pode ser manipulado por esses métodos. - Explique a saída do código abaixo e o motivo:
<script>
for (var i = 0; i < 3; i++) {
setTimeout(function() { console.log(i); }, 100);
}
</script>
Depois modifique para exibir 0, 1, 2.