Introdução: Por que o JavaScript é um campo minado para iniciantes?
\nJavaScript (especialmente no ambiente Node.js) é uma linguagem com um enorme número de armadilhas. Sua natureza dinâmica e assincronicidade muitas vezes confundem até mesmo aqueles que já dominam Python ou Java. Parece que o código funciona, mas no momento mais inoportuno aparece undefined is not a function ou NaN.
Neste artigo, analisaremos os principais erros de desenvolvedores JavaScript iniciantes — desde erros de digitação banais até armadilhas conceituais profundas. Cada item virá com um exemplo real em Node.js e uma explicação de como corrigi-lo. Vamos lá!
\n\n\n\n
1. Confusão com var, let e const (Escopo)
\nO erro mais comum de um iniciante é usar var em vez de let ou const. Em Node.js (especialmente no modo estrito), isso leva a um comportamento inesperado devido ao hoisting.
Problema
\nVariáveis declaradas com var têm escopo de função, não de bloco.
// Exemplo de erro\nfunction testLoop() {\n for (var i = 0; i < 5; i++) {\n setTimeout(() => console.log(i), 100);\n }\n}\ntestLoop(); // Exibe: 5, 5, 5, 5, 5 (e não 0,1,2,3,4)\n\nSolução
\nSempre use let para variáveis mutáveis e const para variáveis imutáveis. É melhor não usar var.
// Código corrigido\nfunction testLoopFixed() {\n for (let i = 0; i < 5; i++) {\n setTimeout(() => console.log(i), 100);\n }\n}\ntestLoopFixed(); // Exibe: 0, 1, 2, 3, 4\n\n\n\n
2. Ignorar a assincronicidade (Callback Hell e Promise)
\nNode.js é construído sobre assincronicidade. Tentar escrever código como se ele fosse executado sequencialmente (como em Python) leva ao Callback Hell e a condições de corrida.
\n\nProblema
\nCallbacks aninhados e tentativa de obter dados antes de serem carregados.
\n\n// Ruim: Callback Hell\nconst fs = require('fs');\n\nfs.readFile('file1.txt', 'utf8', (err, data1) => {\n fs.readFile('file2.txt', 'utf8', (err, data2) => {\n // ... e assim por diante\n console.log(data1 + data2);\n });\n});\n\nSolução
\nUse async/await e Promise.all(). Isso torna o código linear e legível.
// Bom: async/await\nconst fs = require('fs').promises;\n\nasync function readFiles() {\n try {\n const [data1, data2] = await Promise.all([\n fs.readFile('file1.txt', 'utf8'),\n fs.readFile('file2.txt', 'utf8')\n ]);\n console.log(data1 + data2);\n } catch (err) {\n console.error('Erro ao ler arquivo:', err);\n }\n}\nreadFiles();\n\n\n\n
3. Não entender o contexto de this
\nEm JavaScript, this não é definido por onde a função é escrita, mas por como ela é chamada. Em Node.js (fora de métodos de objeto), this referencia um objeto vazio {}, e não global (como no navegador).
Problema
\nPerda de contexto ao passar um método como callback.
\n\nconst user = {\n name: 'Alexey',\n greet() {\n console.log(`Olá, ${this.name}!`);\n }\n};\n\nsetTimeout(user.greet, 1000); // Exibe: "Olá, undefined!"\n\nSolução
\nUse uma arrow function (ela não cria seu próprio this) ou o método .bind().
// Opção 1: bind\nsetTimeout(user.greet.bind(user), 1000);\n\n// Opção 2: arrow function\nsetTimeout(() => user.greet(), 1000); // "Olá, Alexey!"\n\n\n\n
4. Comparação com == em vez de ===
\nO operador == faz coerção de tipos, o que frequentemente dá resultados inesperados. Em N