Como passar em uma entrevista de JavaScript: as principais perguntas de nível avançado
\n\nA entrevista para a posição de Desenvolvedor JavaScript Sênior ou Engenheiro Node.js não é apenas uma verificação de sintaxe. Os entrevistadores querem ver um profundo entendimento da linguagem: como funciona o Event Loop, o que é o contexto this na realidade e como evitar o "inferno" de aninhamento ao trabalhar com assincronia. Neste artigo, analisaremos as perguntas mais frequentes e traiçoeiras feitas em nível avançado. Prepare-se não apenas para ler as respostas, mas para entender a mecânica.
1. Event Loop, pilha de chamadas e microtarefas (Microtasks vs Macrotasks)
\n\nEste é, sem dúvida, o bloco mais popular em entrevistas de Node.js. A pergunta é: "O que este código exibirá e em qual ordem?".
\n\nconsole.log('1');\n\nsetTimeout(() => console.log('2'), 0);\n\nPromise.resolve().then(() => console.log('3'));\n\nprocess.nextTick(() => console.log('4'));\n\nconsole.log('5');\n\nResposta correta: 1, 5, 4, 3, 2.
\n\nAnálise:
\n- \n
- Código síncrono (1, 5) é executado primeiro. \n
- process.nextTick() — é uma microtarefa de maior prioridade. Ela é executada imediatamente após a operação atual, mas ANTES de quaisquer outras microtarefas (Promise) e macrotarefas (setTimeout). \n
- Promise.then() — também é uma microtarefa, mas sua prioridade é menor que a de
nextTick. \n - setTimeout(cb, 0) — é uma macrotarefa. Ela é executada somente depois que a pilha de chamadas e todas as microtarefas (todos os
nextTickePromise) forem completamente limpas. \n
Como responder corretamente: Explique que o Node.js tem fases do Event Loop. As microtarefas (process.nextTick e Promise) são processadas entre as fases. As macrotarefas (setTimeout, setInterval, I/O) são processadas dentro das fases. nextTick é uma fila não padrão, mas muito importante, que pode bloquear o Event Loop se usada recursivamente.
2. Contexto this e sua "perda"
\n\nPergunta: "Como funciona o this em JavaScript? Dê um exemplo onde this é perdido e como corrigir isso".
O nível avançado implica que você conhece as 4 regras:
\n- \n
- Nova vinculação (new binding) — ao chamar uma função com
new,thisaponta para o novo objeto criado. \n - Vinculação explícita —
call,apply,bind. \n - Vinculação implícita — quando a função é chamada como método de um objeto (obj.method()). \n
- Padrão — o objeto global (
globalno Node.js,windowno navegador) ouundefinedno modo estrito. \n
Exemplo de perda de contexto:
\nconst user = {\n name: 'Alice',\n greet() {\n console.log(`Olá, ${this.name}`);\n }\n};\n\nconst greetFn = user.greet;\ngreetFn(); // Olá, undefined\n\nPor quê? Atribuímos o método a uma variável. Agora greetFn() é chamada sem o contexto do objeto (user). this é vinculado ao objeto global (ou undefined no modo estrito).
Como corrigir:
\n- \n
- Usar
bind:const greetFn = user.greet.bind(user);\n - Usar uma função arrow (ela não tem seu próprio
this, mas o pega do escopo léxico externo). \n - Chamar via
call/apply:greetFn.call(user). \n
Pergunta bônus: "E o que acontece se user.greet for passado para setTimeout?" — O mesmo efeito de perda. Corrige-se com bind ou função arrow no callback.