Executando verificação de segurança...
0

As Lacunas de JavaScript que Todo Dev Ignora (e Paga Caro Depois)



## O Problema Real

Você sabe escrever JavaScript. Faz componentes React, consome APIs, usa npm. Mas quando algo quebra de verdade, você congela.

Isso acontece porque existem **lacunas fundamentais** que tutoriais de YouTube nunca cobrem. São conceitos que parecem "teóricos demais" até o dia em que um bug em produção te faz perder 8 horas.

Vou cobrir cada uma dessas lacunas. Com código real. Sem enrolação.

## Lacuna 1: Coerção de Tipos

JavaScript é fracamente tipado. Isso significa que o motor faz conversões implícitas o tempo todo. A maioria dos devs decora que `==` é ruim e `===` é bom. Mas não entende **por quê**.

### O que realmente acontece

Quando você usa `==`, o JavaScript segue o algoritmo Abstract Equality Comparison da spec ECMAScript. Não é aleatório. Tem regras.

```javascript
// Coerção em ação
console.log(1 == "1");       // true — string vira number
console.log(0 == false);     // true — boolean vira number (false → 0)
console.log("" == false);    // true — ambos viram 0
console.log(null == undefined); // true — caso especial da spec
console.log(null == 0);      // false — null só é == a undefined

// O clássico que quebra lógica de formulário
const input = document.getElementById("quantity").value; // "0"
if (input) {
  console.log("tem valor!"); // Executa! "0" é truthy como string
}
if (Number(input)) {
  console.log("tem quantidade!"); // NÃO executa. 0 é falsy.
}

A armadilha do typeof

console.log(typeof null);        // "object" — bug histórico, nunca corrigido
console.log(typeof undefined);   // "undefined"
console.log(typeof NaN);         // "number" — sim, Not-a-Number é number
console.log(NaN === NaN);        // false — NaN não é igual a si mesmo

// Como verificar NaN corretamente
console.log(Number.isNaN(NaN));           // true
console.log(Number.isNaN("hello"));       // false (correto!)
console.log(isNaN("hello"));              // true (bugado — converte antes)

Regra prática: use === sempre. Use Number(), String() ou Boolean() para conversões explícitas. Nunca confie em coerção implícita em lógica de negócio.

Lacuna 2: Closures de Verdade

Todo mundo "sabe" closures. Poucos entendem o que acontece na memória.

Uma closure é uma função que captura o ambiente léxico onde foi criada. Não é cópia. É referência viva.

function criarContador() {
  let count = 0; // essa variável "sobrevive" após criarContador() retornar

  return {
    incrementar: () => ++count,
    valor: () => count,
  };
}

const contador = criarContador();
console.log(contador.incrementar()); // 1
console.log(contador.incrementar()); // 2
console.log(contador.valor());       // 2
// A variável `count` não é acessível de fora. Encapsulamento real.

O bug clássico do loop

Esse bug aparece em entrevistas e em código real com frequência assustadora.

// ❌ BUGADO — todas as funções referenciam o mesmo `i`
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// Output: 3, 3, 3

// ✅ CORRETO — `let` cria escopo de bloco por iteração
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100);
}
// Output: 0, 1, 2

// ✅ CORRETO (alternativa com closure explícita)
for (var i = 0; i < 3; i++) {
  ((j) => {
    setTimeout(() => console.log(j), 100);
  })(i);
}
// Output: 0, 1, 2

Com var, existe uma única variável i no escopo da função. As três closures apontam para ela. Quando o setTimeout executa, o loop já terminou e i vale 3.

Com let, cada iteração cria um novo binding. Cada closure captura sua própria cópia.

Closure e vazamento de memória

// ⚠️ Cuidado: closures mantêm referências vivas
function processarDados() {
  const dadosGigantes = new Array(1_000_000).fill("🔥");

  return function resumo() {
    return dadosGigantes.length; // mantém `dadosGigantes` na memória
  };
}

const fn = processarDados();
// `dadosGigantes` NUNCA será coletado pelo GC enquanto `fn` existir

---

Leia o artigo completo em [https://vivodecodigo.com.br/carreira/lacunas-javascript-webdev-tools-beginners](https://vivodecodigo.com.br/carreira/lacunas-javascript-webdev-tools-beginners)
Carregando publicação patrocinada...
1

JavaScript é fracamente tipado. Isso significa que o motor faz conversões implícitas o tempo todo.

Isso aqui está errado, ser fracamente tipado não é realizar conversões implícitas o tempo todo.

É fazer isso do jeito errado

'2'+2 ser 4 não é necessariamente tipagem fraca, algumas linguagens como Lua podem se dar ao luxo, sem ser tipagem fraca, basta que a linguagem tenha operadores que ajustem a coerção implícita de tipos, a + b é sempre soma em Lua, então é OK fazer coerção implícita, em javascript pode ser adição ou concatenação então é um mecanismo fraco fazer a coerção implícita