JavaScript: conceitos-chave para brilhar na entrevista

Rocketseat

Rocketseat

5 min de leitura
javascript
Faaala, Dev! Está se preparando para aquela entrevista técnica e quer garantir que vai brilhar ao responder perguntas sobre JavaScript? Então você está no lugar certo! Neste artigo, vamos explorar os conceitos mais relevantes do JavaScript, aqueles que são fundamentais em entrevistas e que podem transformar o jeito como você aborda a linguagem. Preparado? Bora codar e descomplicar!

Por que JavaScript é tão importante nas entrevistas?

O JavaScript é uma das linguagens mais usadas no mundo da programação. Seja no front-end, no back-end ou até no desenvolvimento de aplicativos móveis, ele está presente. Nas entrevistas técnicas, os recrutadores procuram candidatos que não apenas saibam escrever código, mas que também compreendam os conceitos fundamentais da linguagem. Isso mostra domínio e confiança.
📽️
Veja o vídeo:
Video preview

Os conceitos que você precisa dominar

Vamos direto ao ponto com os principais conceitos que podem aparecer em uma entrevista:

Hoisting

O hoisting no JavaScript ocorre quando as declarações de variáveis e funções são "movidas" para o topo do escopo antes da execução do código. Entretanto, apenas as declarações são elevadas; as inicializações permanecem no local onde foram escritas. Isso pode levar a comportamentos inesperados, principalmente com variáveis declaradas com var.
console.log(nome); // undefined, devido ao hoisting da declaração, mas não da inicialização var nome = "Rocketseat"; saudacao(); // Chamada da função antes da sua declaração, funciona devido ao hoisting function saudacao() { console.log("Olá!"); }
Por outro lado, as declarações com let e const também são afetadas pelo hoisting, mas entram em um "tempo morto" temporal (temporal dead zone), onde o acesso à variável antes da sua declaração resulta em um erro.
console.log(nome); // ReferenceError: Cannot access 'nome' before initialization let nome = "Rocketseat";
Dica de entrevista: explique como evitar problemas relacionados ao hoisting utilizando let e const para garantir um escopo mais previsível e seguro.

Arrow functions

Introduzidas no ES6, as arrow functions oferecem uma sintaxe mais concisa para declarar funções. Elas são particularmente úteis para funções curtas e sem complexidade.
const somar = (a, b) => a + b; // Declaração de uma arrow function que soma dois números console.log(somar(2, 3)); // Saída: 5
Características principais:
  1. Sintaxe concisa: menos código, especialmente para funções de uma única linha.
  1. Herança de this: arrow functions não possuem seu próprio this. Em vez disso, herdam o valor de this do contexto léxico onde foram definidas.
const contador = { valor: 0, incrementar: function () { const aumentar = () => this.valor++; aumentar(); }, }; contador.incrementar(); console.log(contador.valor); // 1
Cuidado: por não terem seu próprio this, as arrow functions podem ser inadequadas para métodos de objetos que dependem de this.
Dica de entrevista: ressalte a diferença entre arrow functions e funções tradicionais, explicando os cenários em que cada uma é mais apropriada.

Contexto do this

O valor de this no JavaScript é determinado pelo contexto em que a função é chamada. Ele pode variar dependendo de onde e como a função é invocada. Em funções normais, o valor de this pode apontar para:
  • O objeto global (em chamadas no escopo global);
  • O objeto pai (em métodos de objetos);
  • Um valor específico quando utilizado com bind, call ou apply.
const pessoa = { nome: "Rocket", apresentar() { console.log(`Oi, eu sou o ${this.nome}`); }, }; pessoa.apresentar(); // Oi, eu sou o Rocket const apresentar = pessoa.apresentar; apresentar(); // undefined, pois 'this' não está mais referenciando o objeto 'pessoa'
Entretanto, arrow functions não possuem seu próprio this. Elas herdam o valor de this do contexto léxico onde foram definidas.
const pessoa = { nome: "Rocket", apresentar: () => { console.log(`Oi, eu sou o ${this.nome}`); // undefined }, }; pessoa.apresentar();
Dica de ouro: compare e contraste o comportamento de this em funções tradicionais e em arrow functions para destacar como elas se diferenciam.
📽️
Veja o vídeo:
Video preview

Closures

Uma closure é criada quando uma função interna "lembra" das variáveis do escopo da função externa, mesmo após a função externa ter sido executada. Isso é útil para criar funcionalidades como encapsulamento e armazenamento de estados.
function contador() { let count = 0; return function () { count++; // Incrementa o contador return count; // Retorna o valor atualizado de 'count' }; } const meuContador = contador(); console.log(meuContador()); // Saída: 1 console.log(meuContador()); // Saída: 2
Aqui, a função interna preserva o acesso à variável count mesmo após a execução de contador.
Aplicação prática:
  1. Criar funções privadas para proteger dados sensíveis.
  1. Implementar memoization para otimizar cálculos caros, reutilizando resultados já computados.
function memorizar(func) { const cache = {}; return function (arg) { if (cache[arg]) { return cache[arg]; } cache[arg] = func(arg); return cache[arg]; }; } const quadrado = memorizar((n) => n * n); console.log(quadrado(4)); // Calcula e armazena: 16 console.log(quadrado(4)); // Retorna do cache: 16
Dica: explique como closures ajudam a implementar encapsulamento em JavaScript, simulando comportamento de "private variables".

Escopo

O escopo no JavaScript define onde as variáveis, funções e objetos são acessíveis no código. Existem dois tipos principais:
  • Escopo global: variáveis declaradas fora de qualquer função ou bloco estão disponíveis em toda a aplicação.
  • Escopo local: variáveis declaradas dentro de uma função ou bloco só estão acessíveis naquele contexto.
function exemplo() { let local = "Visível apenas aqui"; console.log(local); // Visível apenas aqui } console.log(local); // ReferenceError
Detalhe importante:
  • var: escopo baseado na função. Não respeita blocos (como loops e condicionais).
  • let e const: escopo baseado no bloco. São mais seguras e evitam problemas com reatribuições indesejadas.
if (true) { var global = "Acessível fora do bloco"; let local = "Apenas dentro do bloco"; } console.log(global); // Acessível fora do bloco console.log(local); // ReferenceError
Dica de entrevista: explique como o uso de let e const previne erros comuns, como a redefinição acidental de variáveis em escopos diferentes.
📽️
Veja o vídeo:
Video preview

Prototypes e herança

O JavaScript utiliza herança prototípica, um modelo onde objetos podem herdar propriedades e métodos de outros objetos. Cada objeto tem uma propriedade chamada __proto__, que aponta para o protótipo de onde herda métodos e propriedades.
function Animal(nome) { this.nome = nome; } Animal.prototype.falar = function () { console.log(`${this.nome} faz um som.`); }; const cachorro = new Animal("Buddy"); cachorro.falar(); // Buddy faz um som.
Com o ES6, o uso de classes torna a sintaxe mais intuitiva, mas ainda utiliza o sistema de protótipos por baixo dos panos.
class Animal { constructor(nome) { this.nome = nome; } falar() { console.log(`${this.nome} faz um som.`); } } const gato = new Animal("Miau"); gato.falar(); // Miau faz um som.
Dica de entrevista: compare o modelo de protótipos com o uso de classes ES6 e explique como elas são apenas açúcar sintático para facilitar a leitura e escrita de código.

Event loop

O event loop é um mecanismo central no JavaScript que permite a execução não bloqueante de operações assíncronas. Ele coordena a interação entre a Call Stack, a Web APIs, a Task Queue e a Microtask Queue.
Componentes Principais:
  • Call Stack (Pilha de Chamadas): Onde as funções são empilhadas quando chamadas e desempilhadas quando retornam. Executa código JavaScript de forma síncrona.
  • Web APIs: Fornecem funcionalidades assíncronas (como setTimeout, fetch, eventos de DOM) que não são executadas na Call Stack, mas no ambiente do navegador ou Node.js.
  • Task Queue (Fila de Tarefas): Armazena as macrotarefas, como callbacks de setTimeout, setInterval, e eventos do DOM.
  • Microtask Queue (Fila de Microtarefas): Armazena as microtarefas, como callbacks de Promises (funções passadas para .then() e .catch()), e MutationObserver.
Fluxo de Operação do Event Loop:
  1. Executa a Call Stack: O JavaScript começa executando o código síncrono na Call Stack.
  1. Processa a Microtask Queue: Após a Call Stack estar vazia, o Event Loop verifica a Microtask Queue e executa todas as microtarefas em ordem, antes de processar qualquer tarefa na Task Queue.
  1. Processa a Task Queue: Depois de esvaziar a Microtask Queue, o Event Loop pega a primeira tarefa da Task Queue e a coloca na Call Stack para execução.
  1. Repetição: O processo se repete, garantindo que as microtarefas tenham prioridade sobre as macrotarefas.
Exemplo Detalhado:
console.log("Início"); // 1. Executa e imprime "Início" setTimeout(() => { console.log("Timeout 1"); // 6. Agendado na Task Queue }, 0); Promise.resolve() .then(() => { console.log("Promise 1"); // 4. Agendado na Microtask Queue }) .then(() => { console.log("Promise 2"); // 5. Agendado na Microtask Queue }); console.log("Fim"); // 2. Executa e imprime "Fim" // Ordem de execução: // 1. "Início" // 2. "Fim" // 3. Microtasks: // a. "Promise 1" // b. "Promise 2" // 4. Task Queue: // a. "Timeout 1"
Explicação passo a passo:
  • Passo 1: console.log("Início"); é executado e "Início" é impresso.
  • Passo 2: setTimeout(..., 0); é chamado. O callback é enviado para a Task Queue com tempo mínimo (não exatamente zero).
  • Passo 3: Promise.resolve().then(...).then(...); As funções passadas para .then() são colocadas na Microtask Queue.
  • Passo 4: console.log("Fim"); é executado e "Fim" é impresso.
  • Passo 5: A Call Stack está vazia. O Event Loop verifica a Microtask Queue e executa "Promise 1" e "Promise 2" em ordem.
  • Passo 6: Após esvaziar a Microtask Queue, o Event Loop pega "Timeout 1" da Task Queue e o executa.
Diferença entre task queue e microtask queue:
  • Prioridade: microtasks têm prioridade sobre tasks. Ou seja, todas as microtarefas são executadas antes de qualquer macrotarefa.
  • Uso Comum:
    • Microtasks: Promises, process.nextTick() (Node.js), MutationObserver.
    • Tasks: setTimeout, setInterval, eventos de I/O, eventos do DOM.
Por que isso é importante?
Entender essa diferença é crucial para prever a ordem de execução em código assíncrono, evitando comportamentos inesperados.
Dica de entrevista: ao explicar o Event Loop, demonstre com exemplos como a priorização das microtarefas pode afetar a execução do código. Por exemplo, por que uma Promise é executada antes de um setTimeout com 0ms de delay.

Promises e Async/Await

As Promises permitem lidar com operações assíncronas de forma mais organizada e legível, substituindo o uso excessivo de callbacks.
fetch("https://api.example.com/dados") .then((resposta) => resposta.json()) .then((dados) => console.log(dados)) .catch((erro) => console.error(erro));
Com o ES8, o async/await simplificou ainda mais o fluxo assíncrono, tornando-o similar ao código síncrono.
async function buscarDados() { try { const resposta = await fetch("https://api.example.com/dados"); const dados = await resposta.json(); console.log(dados); } catch (erro) { console.error("Erro ao buscar dados", erro); } }
Dica de entrevista: explique como o uso de try/catch no async/await facilita o tratamento de erros em operações assíncronas complexas.

Map e filter

Os métodos map e filter são usados para transformar e filtrar arrays de forma funcional.
  • map: aplica uma função a cada elemento do array, retornando um novo array.
  • filter: retorna um novo array contendo apenas os elementos que passam em uma condição.
const numeros = [1, 2, 3, 4]; const dobrados = numeros.map((n) => n * 2); // [2, 4, 6, 8] const pares = numeros.filter((n) => n % 2 === 0); // [2, 4]
Dica de entrevista: mostre como map e filter ajudam a escrever código mais limpo e funcional.
📽️

Reduce

O método reduce acumula valores de um array em um único resultado, utilizando um acumulador.
const numeros = [1, 2, 3, 4]; const soma = numeros.reduce((acc, n) => acc + n, 0); // 10

Conheça o Rocketseat Para Empresas

Oferecemos soluções personalizadas para empresas de todos os portes.

Rocketseat

Rocketseat

Ecossistema de educação contínua referência em programação e Inteligência Artificial.

Artigos_

Explore conteúdos relacionados

Descubra mais artigos que complementam seu aprendizado e expandem seu conhecimento.

Imagem contendo uma carta e um símbolo de check
NewsletterReceba conteúdos inéditos e novidades gratuitamente