Depois de alguns anos trabalhando com JavaScript, percebi que muitos dos problemas que enfrentei se tornaram desafiadores simplesmente por eu não conhecer alguns conceitos essenciais. Se eu tivesse dominado esses tópicos antes, certamente teria evitado alguns estresses.
Então eu trouxe 4 conceitos que de alguma forma ficaram na minha cabeça e que eu fiquei simplesmente ANIMADÃO quando aprendi e recomendo dar uma visitada e entender para trabalhar com JavaScript, principalmente para pessoas que estão iniciando e já tem na memória pelo menos os conceitos básicos da linguagem.
1. Closures
Closures são um dos conceitos mais poderosos e, por muitas vezes, confusos no JavaScript, relacionados ao escopo. Elas permitem que uma função "lembre" do ambiente em que foi criada, mesmo depois que esse ambiente não está mais em execução. Isso é útil para criar variáveis "privadas" e gerenciar estados sem poluir o escopo global.
Exemplo:
function criarContador() {
let contador = 0;
return {
incrementar: function() {
contador++;
return contador;
},
obterValor: function() {
return contador;
}
};
}
const meuContador = criarContador();
console.log(meuContador.obterValor()); // 0
console.log(meuContador.incrementar()); // 1
console.log(meuContador.incrementar()); // 2
console.log(meuContador.obterValor()); // 2
No exemplo acima, a função interna acessa a variável contador, que pertence à função externa, mesmo depois de meuContador
já ter retornado valores usando ou obterValor
ou o incrementar
. Isso é possível graças ao closure.
2. Herança Prototípica
Embora o JavaScript ofereça suporte a classes e herança de classes (um conceito bem consolidado em linguagens como Java ou C++), ele se diferencia ao adotar, de forma nativa, um modelo de herança baseado em protótipos. Em JavaScript, todo objeto tem um "protótipo", que serve como uma espécie de blueprint (molde), permitindo que propriedades e métodos sejam compartilhados entre objetos. Esse modelo de herança prototípica é uma das características mais fundamentais da linguagem, tornando-a mais flexível em comparação com a herança tradicional baseada em classes.
Exemplo:
function Carro(nome) {
this.nome = nome;
}
Carro.prototype.buzina = function() {
console.log(`${this.nome} faz um som de buzina`);
}
const camaro = new Carro('Camaro');
camaro.buzina(); // Camaro faz um som de buzina
Aqui, camaro
herda o método buzina
do protótipo de Carro
, demonstrando a ideia de herança em JavaScript. Através da cadeia de protótipos, conseguimos compartilhar comportamentos entre diferentes objetos sem a necessidade de duplicar o código.
3. Currying
Currying é uma técnica que transforma uma função que recebe vários argumentos em uma série de funções que recebem um único argumento de cada vez. Essa abordagem é útil para criar funções reutilizáveis e compor novas funções de maneira mais flexível.
Exemplo:
function somar(a) {
return function(b) {
return a + b;
}
}
const somarTres = somar(3);
console.log(somarTres(3)); // 6
No exemplo, somar(5)
retorna uma nova função que recebe o segundo argumento, permitindo que se reutilize a lógica em diferentes partes do código.
4. Event Loop e Callbacks
O Event Loop é um conceito fundamental para entender como o JavaScript lida com operações assíncronas — e rapaz, entender isso foi um divisor de águas no meu aprendizado de JavaScript. O que ele faz, basicamente, é monitorar a Call Stack (onde o código sincrônico é executado) e a Event Queue (onde ficam armazenadas as tarefas assíncronas, como callbacks, eventos e promessas). Quando a Call Stack está vazia, o Event Loop pega as tarefas da Event Queue e as coloca na pilha para serem executadas. Isso garante que o JavaScript consiga continuar rodando o código sem bloquear outras operações, algo essencial para manter a fluidez de aplicações que lidam com eventos de I/O, timers, e interações com o DOM.
Exemplo:
console.log('Início');
setTimeout(() => {
console.log('Timer expirou');
}, 0);
console.log('Fim');
// Saída:
// Início
// Fim
// Timer expirou
Mesmo que o setTimeout seja configurado para 0 milissegundos, ele é colocado no Event Queue e só será executado após o código sincrônico (como os console.log) ter sido processado.
Pretendo detalhar isso melhor e com imagens em outro artigo focado nesse conceito, pois pra mim foi muito importante entender e tenho certeza que pra muitas pessoas vai ser também.
Você gostaria de saber mais sobre algum desses conceitos ou tem dúvidas específicas? Deixe nos comentários que eu vou dar uma olhada!
Top comments (0)