JavaScript sem tiro no pé

Evite bugs na produção com práticas simples de JavaScript sem tiro no pé: const/let, ===, async/await, ESM e imutabilidade. Leia e aplique hoje.

Avatar de Danrley Pereira
Danrley Pereira
JavaScript sem tiro no pé

JavaScript te deixa fazer quase tudo. O problema é que "quase tudo" inclui um monte de coisa que vai explodir na sua mão em produção, três semanas depois, num horário ruim. A boa notícia: a maioria dos tiros no pé vem de um punhado de hábitos, e todos têm cura. Aqui vão os que mais rendem.

Imagem de capa/abertura que traduz visualmente a ideia de "boas práticas de JavaScript" — código organizado e previsível em contraste com armadilhas evitadas.
Imagem de capa/abertura que traduz visualmente a ideia de "boas práticas de JavaScript" — código organizado e previsível em contraste com armadilhas evitadas.

Aposente o var: só const e let

Não existe motivo pra usar var em código novo. Ele vaza escopo de função, sobe pro topo com hoisting e te deixa reatribuir sem querer. Use const por padrão e só troque pra let quando você REALMENTE for reatribuir a variável.

const taxa = 0.15;
let total = 0;
for (const item of carrinho) total += item.preco;

Regra prática: comece tudo como const. Se o linter reclamar que precisa reatribuir, aí vira let. var é código de 2014.

=== sempre, == nunca

O == faz coerção de tipo antes de comparar, e as regras são um pequeno campo minado. 0 == '' é true. null == undefined é true. [] == false é true. Ninguém tem essa tabela na cabeça, e você não devia precisar.

if (valor === 0) { /* previsível */ }

Use === e !== sempre. Se precisar tratar null/undefined juntos, seja explícito nesse caso pontual — ou resolva com ??.

async/await no lugar do inferno de callbacks

Callback aninhado dentro de callback dentro de callback é a famosa pirâmide da desgraça. async/await deixa código assíncrono parecer síncrono, linha após linha.

async function carregarPerfil(id) {
  const user = await buscarUsuario(id);
  const posts = await buscarPosts(user.id);
  return { user, posts };
}

Precisa de coisas em paralelo? Promise.all em vez de await em série:

const [user, config] = await Promise.all([buscarUsuario(id), buscarConfig(id)]);

Promise sem tratamento é bomba-relógio

async/await bonito não te salva de erro. Uma promise que rejeita e ninguém pega vira um unhandledRejection — em Node moderno, isso derruba o processo.

try {
  const dados = await buscarDados();
  usar(dados);
} catch (err) {
  logger.error('falha ao buscar dados', err);
  // decida: fallback, re-throw ou responder erro
}

Toda operação assíncrona que pode falhar precisa de um try/catch ou de um .catch(). "Depois eu trato" é como bug de produção nasce.

ESM e imutabilidade: menos surpresa, menos bug

Use módulos ESM (import/export), não variáveis globais nem require espalhado. Módulo deixa explícito o que entra e o que sai, o bundler faz tree-shaking, e nada vaza pro escopo global sem você ver.

// util.js
export function slugify(texto) { /* ... */ }
// app.js
import { slugify } from './util.js';

Junto disso, evite mutar dados sem necessidade. map, filter e reduce retornam novos arrays em vez de mexer no original — menos efeito colateral, menos bug fantasma.

const ativos = usuarios.filter(u => u.ativo);
const nomes = ativos.map(u => u.nome);

Mutação não é proibida, mas quando você precisa dela, que seja uma decisão consciente — não um acidente.

O this não é seu amigo

this em JavaScript depende de COMO a função é chamada, não de onde ela foi definida. Passe um método como callback e o this some.

class Timer {
  segundos = 0;
  // arrow preserva o this da instância
  tick = () => { this.segundos++; };
}
setInterval(timer.tick, 1000); // funciona

Arrow functions não têm this próprio — herdam do escopo onde foram criadas. Por isso resolvem 90% das dores de cabeça com callbacks. Só cuidado: NÃO use arrow como método quando você depende de this dinâmico (por exemplo, handlers do DOM que esperam this = elemento).

Nenhuma dessas práticas é sofisticada. São hábitos pequenos que, somados, transformam "por que isso quebrou?" em código que faz exatamente o que parece que faz. E código previsível é o único tipo que você consegue manter às duas da manhã.

Gostou do artigo?

Compartilhe com seus amigos e ajude a espalhar conhecimento!