Fácil JavaScript
Contador com closure
Enunciado
Crie uma função criarContador que retorna uma função. Cada chamada da função retornada incrementa e retorna um contador interno. O contador deve começar em 0 e ser privado (não acessível de fora).
Requisitos
- A função
criarContadornão recebe parâmetros. - A função retornada incrementa e retorna o valor atual do contador.
- Duas instâncias de
criarContadordevem ter contadores independentes.
Código inicial
function criarContador() {
// seu código aqui
}
const c1 = criarContador();
const c2 = criarContador();
console.log(c1()); // 1
console.log(c1()); // 2
console.log(c2()); // 1
Saída esperada
1
2
1
Ver dica
Use uma variável local dentro de criarContador e retorne uma função que a modifique.
Mostrar solução
function criarContador() {
let count = 0; // variável privada no escopo da função externa
return function() {
count++;
return count;
};
}
const c1 = criarContador();
const c2 = criarContador();
console.log(c1()); // 1
console.log(c1()); // 2
console.log(c2()); // 1
Passo a passo
- Declaramos
criarContadorcomo uma função que não recebe parâmetros. - Dentro dela, criamos a variável
countinicializada com 0. Essa variável é local ao escopo decriarContador. - Retornamos uma função anônima que, quando chamada, incrementa
counte retorna o novo valor. - Como a função interna referencia
count, ela forma uma closure que mantémcountvivo mesmo apóscriarContadorretornar. - Cada chamada a
criarContadorcria um novo escopo, portantoc1ec2têm contadores independentes.
Por que funciona
A closure captura o ambiente léxico onde foi criada, incluindo a variável count. Assim, cada instância de criarContador tem seu próprio count isolado. Isso demonstra encapsulamento e estado privado.
Erros comuns
- Declarar
countfora da função: secountfor global, todos os contadores compartilharão o mesmo valor.
Isso fazlet count = 0; function criarContador() { return function() { count++; return count; }; }c1ec2compartilharemcount. - Esquecer de retornar a função interna: se não houver
return, a função externa retornaundefined. - Usar
varem vez delet: não é um erro aqui, masvartem escopo de função; ainda funcionaria, masleté mais claro.
Outra forma de resolver
Usar um objeto com método:
function criarContador() {
let count = 0;
return {
incrementar: function() { return ++count; }
};
}
const c = criarContador();
console.log(c.incrementar()); // 1
Preferível quando se deseja expor múltiplos métodos.
Saída esperada
1
2
1