DEV Community

Leomar Linhares
Leomar Linhares

Posted on

4 Conceitos legais do JavaScript que você vai achar legal também

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


Enter fullscreen mode Exit fullscreen mode

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


Enter fullscreen mode Exit fullscreen mode

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


Enter fullscreen mode Exit fullscreen mode

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


Enter fullscreen mode Exit fullscreen mode

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)