0Pricing
JavaScript Academy · Aula

Como closures capturam o estado

Entenda o ambiente léxico das closures.

Como closures capturam o estado é uma aula grátis de JavaScript Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de JavaScript Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de JavaScript Academy inclui 4 aulas no total.

O que é um fechamento

Um fechamento é uma função agrupada com referências às variáveis do escopo onde foi definida. A função interna "lembra" essas variáveis mesmo depois de a função externa ter retornado.

function outer() {
  const message = "hello";
  function inner() {
    console.log(message); // sees outer variable
  }
  inner();
}
outer(); // "hello"

Retornando a função interna

A parte especial aparece quando a função interna é retornada. Ela mantém acesso à variável externa, embora outer já tenha terminado de ser executada.

function outer() {
  const message = "remembered";
  return function () {
    console.log(message);
  };
}
const fn = outer();
fn(); // "remembered"

Escopo léxico

Os fechamentos funcionam por causa do escopo léxico: uma função pode acessar variáveis definidas nos escopos que a envolvem fisicamente no código-fonte, não no local de onde é chamada.

const x = 10;
function show() {
  console.log(x); // resolves where defined
}
function run() {
  const x = 99;
  show(); // still logs 10, not 99
}
run();

Capturando por referência

Um fechamento captura a própria variável, não uma fotografia do seu valor. Se a variável mudar depois, o fechamento verá o novo valor.

function make() {
  let count = 0;
  const get = () => count;
  count = 5; // changed after get defined
  return get;
}
console.log(make()()); // 5

Cada chamada cria um novo escopo

Cada invocação da função externa cria um conjunto novo de variáveis. Fechamentos de chamadas diferentes não compartilham estado.

function counter() {
  let n = 0;
  return () => ++n;
}
const a = counter();
const b = counter();
console.log(a(), a()); // 1 2
console.log(b());      // 1 (independent)

Fechamentos sobre parâmetros

Os parâmetros de funções também são capturados. Isso permite criar funções especializadas a partir de uma função geral.

function adder(x) {
  return (y) => x + y;
}
const add5 = adder(5);
console.log(add5(3));  // 8
console.log(add5(10)); // 15

A armadilha clássica dos laços

Um erro famoso: usar var em um laço compartilha uma única variável entre todos os fechamentos. Quando eles são executados, o laço já terminou e todos veem o valor final.

const fns = [];
for (var i = 0; i < 3; i++) {
  fns.push(() => i);
}
console.log(fns[0](), fns[1](), fns[2]()); // 3 3 3

Corrigindo com uma declaração de bloco

let cria uma nova vinculação a cada iteração, portanto cada fechamento captura seu próprio i. Essa é a correção moderna.

const fns = [];
for (let i = 0; i < 3; i++) {
  fns.push(() => i);
}
console.log(fns[0](), fns[1](), fns[2]()); // 0 1 2

Fechamentos mantêm a memória ativa

Enquanto um fechamento existir, as variáveis que ele captura não poderão ser coletadas pelo coletor de lixo. Isso geralmente não é um problema, mas pode causar vazamentos se você mantiver fechamentos por mais tempo do que o necessário.

function make() {
  const big = new Array(3).fill("data");
  return () => big.length;
}
const f = make();
console.log(f()); // 3 - big stays in memory via f

Fechamentos estão em toda parte

Funções de retorno, manipuladores de eventos, setTimeout, métodos de matriz e promessas dependem de fechamentos para lembrar o contexto. Você os usa constantemente, muitas vezes sem perceber.

function greet(name) {
  return () => console.log("Hi " + name);
}
[greet("Ada"), greet("Bob")].forEach((fn) => fn());
// Hi Ada
// Hi Bob

Inspecionando o estado capturado

Vários fechamentos provenientes da mesma chamada compartilham as mesmas variáveis capturadas, portanto um pode ler o que outro escreve.

function pair() {
  let value = 0;
  return {
    set: (v) => { value = v; },
    get: () => value
  };
}
const p = pair();
p.set(42);
console.log(p.get()); // 42

Verificação rápida

Como os fechamentos capturam o estado.

Recapitulação

Um fechamento é uma função mais referências ao seu escopo de definição. Graças ao escopo léxico, ele se lembra das variáveis externas depois que a função externa retorna, capturando-as por referência, não por valor. Cada chamada externa cria um escopo independente; use let para evitar a armadilha dos laços. Os fechamentos mantêm a memória capturada ativa e dão suporte a funções de retorno em toda parte.

Perguntas Frequentes

A aula “Como closures capturam o estado” é grátis?

Sim — o texto completo de “Como closures capturam o estado” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de JavaScript Academy, atualize para CoddyKit PRO. O curso de JavaScript Academy inclui 4 aulas no total.

O que vou aprender em “Como closures capturam o estado”?

Entenda o ambiente léxico das closures. Você pratica JavaScript Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar JavaScript Academy?

Nenhuma experiência prévia é necessária. JavaScript Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.

Quanto tempo leva a aula “Como closures capturam o estado”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de JavaScript Academy?

Sim. Cada aula de JavaScript Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Como closures capturam o estado
  2. Variáveis privadas com closures
  3. O padrão de módulo (IIFE)
  4. Funções fábrica
← Voltar para JavaScript Academy