Variables
A forma como você declara uma variável controla três coisas: o scope (escopo, onde a variável existe e pode ser usada), se o valor pode ser trocado depois, e o hoisting (içamento, o momento em que a declaração é processada). Errar a escolha vaza a variável para fora do bloco, abre espaço para uma troca acidental de valor e embaralha o raciocínio sobre o fluxo.
Na dúvida, use const. Troque por let só quando precisar reatribuir o valor. E
não use var: ele é legado e vaza para fora do bloco.
Conceitos fundamentais
| Conceito | O que é |
|---|---|
| const (constante) | Declaração de bloco fixa: a referência não pode ser alterada após atribuída |
| let (deixar / permitir) | Declaração de bloco que pode mudar: aceita reatribuição no mesmo escopo |
| var (variável) | Declaração de função (legado): vaza para fora do bloco e permite redeclaração silenciosa |
| block scope (escopo de bloco) | Visibilidade limitada às chaves { } mais próximas |
| hoisting (içamento) | Antecipação da declaração para o topo do escopo na fase de parsing |
| TDZ (Temporal Dead Zone · Zona Morta Temporal) | Trecho entre o início do bloco e a declaração let/const onde acessar a variável lança erro |
var: escopo de função, não de bloco
❌ Ruim
if (true) {
var leaked = 50; // vaza para fora do bloco
}
console.log(leaked); // 50: comportamento inesperado
var count = 10;
var count = 20; // redeclaração silenciosa
✅ Bom
if (true) {
const contained = 50;
}
console.log(contained); // ReferenceError: escopo correto
let desnecessário
❌ Ruim: let onde const seria suficiente
let MAX_RETRIES = 3; // nunca reatribuído
let userName = "Alice"; // nunca reatribuído
✅ Bom: const por padrão, let só quando necessário
const MAX_RETRIES = 3;
const userName = "Alice";
let attempt = 0;
while (attempt < MAX_RETRIES) {
attempt++;
}
Alteração direta de objetos
Objetos são passados por referência: quando você altera um parâmetro dentro da função, muda também o objeto lá fora, na mão de quem chamou. Esse é um efeito colateral invisível e difícil de rastrear. Em vez disso, devolva um objeto novo com os valores que mudaram.
❌ Ruim: mutação acoplada e difícil de rastrear
function applyDiscount(order) {
order.discount = 10; // altera o objeto recebido
order.total -= 10; // efeito colateral escondido
}
✅ Bom: retorna novo estado, sem efeitos colaterais
function applyDiscount(order) {
const discountedOrder = {
...order,
discount: 10,
total: order.total - 10,
};
return discountedOrder;
}
Evitar valores mágicos
Um número ou texto solto no meio do código não conta o que significa. Uma
constante com nome coloca a intenção à vista: MINIMUM_DRIVING_AGE explica o que
o 18 cru escondia.
❌ Ruim: o que significa 18? e 86400000?
if (user.age >= 18) {
/* ... */
}
if (order.status === 2) {
/* ... */
}
setTimeout(syncData, 86400000);
✅ Bom: constantes nomeadas
const MINIMUM_DRIVING_AGE = 18;
const ORDER_STATUS_APPROVED = 2;
const ONE_DAY_MS = 86_400_000;
if (user.age >= MINIMUM_DRIVING_AGE) {
/* ... */
}
if (order.status === ORDER_STATUS_APPROVED) {
/* ... */
}
setTimeout(syncData, ONE_DAY_MS);
DoDocs v3.7.0 · Desenvolvido por @thiagocajadev · Baseado no trabalho de pmndrs/docs · Poimandres.