Optional Chaining (?.)
O Optional Chaining é um operador que permite acessar propriedades profundas de um objeto sem necessidade de validações intermináveis. Introduzido no ES2020, ele resolve um problema clássico: quando você tenta acessar uma propriedade de um valor nulo ou indefinido, JavaScript lança um erro. Com ?., a operação retorna undefined graciosamente em vez de quebrar sua aplicação.
O operador funciona em três contextos: acesso a propriedades (obj?.prop), chamadas de método (func?.()), e acesso a índices (arr?.[0]). Quando o valor antes do ?. é null ou undefined, toda a cadeia de avaliação para e retorna undefined. Caso contrário, continua normalmente.
const usuario = {
perfil: {
endereco: {
cidade: "São Paulo"
}
}
};
// Sem optional chaining (arriscado)
const cidade = usuario.perfil.endereco.cidade; // "São Paulo"
// const rua = usuario.perfil.endereco.rua; // undefined (OK)
// const cep = usuario.perfil.telefone.cep; // TypeError!
// Com optional chaining (seguro)
const cep = usuario?.perfil?.endereco?.cep; // undefined
const telefone = usuario?.contato?.telefone; // undefined
const metodo = usuario?.getInfo?.(); // undefined se não existir
// Com arrays
const items = usuario?.pedidos?.[0]?.id; // undefined se pedidos não existir
Quando usar Optional Chaining
Use quando trabalhar com dados de APIs, respostas assincronamente carregadas ou estruturas que você não controla totalmente. É especialmente útil em requisições HTTP onde a resposta pode ter propriedades ausentes. Evite usar quando a propriedade deve existir — nesse caso, deixe o erro vir para identificar o problema real.
Nullish Coalescing (??)
O Nullish Coalescing, também do ES2020, é um operador lógico que retorna o operando à direita apenas quando o da esquerda é null ou undefined. Diferente do ||, ele não trata valores falsos como vazios: 0, "" e false são valores válidos.
Esse detalhe é crucial em programação real. Se você usa || e recebe 0 como quantidade de itens ou false como flag booleana, inadvertidamente substituirá esses valores legítimos pelo padrão. O ?? resolve isso elegantemente.
// Problema com ||
const quantidade = 0;
const valor = quantidade || 10; // 10 (incorreto! 0 é válido)
// Solução com ??
const valor2 = quantidade ?? 10; // 0 (correto!)
// Com strings
const nome = "" ?? "Anônimo"; // "" (mantém string vazia)
const nome2 = "" || "Anônimo"; // "Anônimo" (substitui)
// Em APIs
const config = {
timeout: 0,
retries: false,
debug: undefined
};
const timeout = config.timeout ?? 5000; // 0
const retries = config.retries ?? 3; // false
const debug = config.debug ?? true; // true
Combinando com Optional Chaining
A combinação ?. com ?? é poderosa. Você acessa a propriedade seguramente e fornece um padrão se ela não existir:
const resposta = {
dados: { contador: 0 }
};
const contador = resposta?.dados?.contador ?? 100; // 0
const prioridade = resposta?.config?.nivel ?? "média"; // "média"
Logical Assignment Operators
Os operadores de atribuição lógica (introduzidos no ES2021) combinam operadores lógicos com atribuição: &&=, ||= e ??=. Eles atribuem um valor apenas se a condição lógica for satisfeita, evitando código verboso com if.
||= atribui se o valor é falso (falsy). &&= atribui se o valor é verdadeiro (truthy). ??= atribui se é null ou undefined. Cada um tem seu caso de uso, e escolher o correto evita bugs sutis.
// ||= : atribui se falsy
let usuario = null;
usuario ||= { nome: "Padrão" }; // { nome: "Padrão" }
let contador = 0;
contador ||= 10; // 10 (problema: 0 é válido!)
// &&= : atribui se truthy
let config = { ativo: true };
config.ativo &&= false; // false
config.ativo &&= "novo"; // "novo"
let vazio = null;
vazio &&= "novo"; // null (não muda)
// ??= : atribui se null ou undefined (recomendado para padrões)
let valor = 0;
valor ??= 100; // 0 (mantém!)
let resultado = undefined;
resultado ??= "padrão"; // "padrão"
// Caso real: inicializar objeto
const obj = {};
obj.cache ??= [];
obj.cache.push("item"); // inicializa apenas uma vez
Padrão prático: Configurações com Fallbacks
function iniciarApp(opcoes = {}) {
// Padrões seguros e legíveis
opcoes.porta ??= 3000;
opcoes.debug ??= false;
opcoes.timeout ??= 5000;
// Ativar logs apenas se debug é true
opcoes.debug &&= console.log;
// Usar cache apenas se disponível
let dados = opcoes.cache || fetch("/dados");
return opcoes;
}
const config = iniciarApp({ debug: true, porta: 8080 });
// { porta: 8080, debug: true, timeout: 5000 }
Conclusão
Esses três recursos modernos resolvem problemas reais de segurança e legibilidade em JavaScript. Optional Chaining elimina verificações nulas repetitivas quando navega estruturas profundas. Nullish Coalescing fornece padrões sem sobrescrever valores falsos legítimos como 0 e false. Logical Assignment torna código declarativo e evita blocos if desnecessários.
O aprendizado prático é: use ?. ao acessar propriedades incertas, ?? para padrões seguros, e ??= para inicializações. Combine-os estrategicamente, e seu código será mais robusto e expressivo. A chave é entender quando cada um é apropriado — não são substitutos uns dos outros, mas complementos em diferentes cenários.