Menu

Operador ?? no JavaScript: valores padrão sem dor de cabeça

Entenda como o operador ?? devolve um valor padrão apenas quando o valor é null ou undefined — e por que ele resolve melhor que o || na maioria dos casos reais.

Um valor padrão mais esperto

O JavaScript sempre teve um atalho para definir valores padrão: value || fallback. Funciona na maioria dos casos, só que traz um probleminha embutido — ele considera qualquer valor falsy como ausente. Ou seja, 0, '' e false acionam o fallback, mesmo quando são exatamente a resposta que você queria.

O operador de nullish coalescing ?? resolve isso. Ele só cai no fallback quando o valor é null ou undefined:

index.js
Output
Click Run to see the output here.

0 e '' sobrevivem. null e undefined não. É isso que o operador faz, em resumo.

Por que o || não resolve

Esse é o bug clássico que o ?? veio corrigir:

index.js
Output
Click Run to see the output here.

O usuário pediu volume 0 (silêncio) e um nickname vazio. Os dois foram sobrescritos sem aviso, porque o || não consegue diferenciar "ausente" de "falsy".

Troque pelo ??:

index.js
Output
Click Run to see the output here.

Agora 0 e '' passam sem serem alterados, e só os campos realmente ausentes recebem o valor padrão. Na prática, é quase sempre isso que você quer.

O modelo mental

O ?? faz uma única pergunta: o lado esquerdo é null ou undefined? Nada além disso importa.

Valor à esquerdaleft || right retornaleft ?? right retorna
nulldireitadireita
undefineddireitadireita
0direitaesquerda (0)
''direitaesquerda ('')
falsedireitaesquerda (false)
NaNdireitaesquerda (NaN)
qualquer objetoesquerdaesquerda

Use ?? quando seus dados tiverem valores falsy que fazem sentido. Use || quando você realmente quiser descartar tudo que for falsy (strings vazias, contagens zeradas e afins) — esse caso existe, mas é bem menos comum do que muita gente imagina.

Avaliação em curto-circuito

Assim como || e &&, o ?? também faz curto-circuito. Se o lado esquerdo não for nullish, o lado direito nem chega a ser executado:

index.js
Output
Click Run to see the output here.

expensiveDefault() roda uma vez só — no caso do b. Isso é ótimo quando o seu fallback é uma chamada de função, uma requisição de rede ou qualquer coisa que você prefere evitar quando não for necessário.

Combinando com optional chaining

O ?? e o ?. chegaram juntos no ES2020, e foram pensados para trabalhar em dupla. O optional chaining percorre um caminho que pode não existir e devolve undefined caso algum trecho esteja faltando; já o nullish coalescing entra em cena para fornecer um valor padrão coerente:

index.js
Output
Click Run to see the output here.

Sem essa dupla, o mesmo código vira uma sequência feia de && ou um try/catch. Com elas, acesso seguro e valores padrão cabem em uma única linha.

Atribuição com nullish: ??=

a ??= b atribui b a a apenas quando a é null ou undefined. Esse é o operador de atribuição lógica nullish, e ele tem short-circuit — se a já tem um valor, o lado direito nem chega a ser avaliado.

index.js
Output
Click Run to see the output here.

Repare que verbose: false e retries: 0 foram preservados — o ??= só preenche o que realmente está faltando. Compare com o ||=, que sobrescreveria os dois.

Precedência e a regra dos parênteses

O ?? se recusa de propósito a ser misturado com || ou && sem parênteses. Isso gera um SyntaxError:

const x = a || b ?? c;   // SyntaxError

Os criadores da linguagem acharam que a precedência aqui era ambígua o suficiente para exigir que você deixe explícito. Basta colocar parênteses que tudo funciona:

index.js
Output
Click Run to see the output here.

Agrupamentos diferentes, resultados diferentes. Os parênteses não estão ali só de enfeite — eles deixam claro para quem vai ler o código depois (e para o parser) qual era a sua intenção.

Não é a mesma coisa que parâmetro padrão

Os parâmetros padrão na assinatura de uma função seguem outra regra: eles só entram em ação quando o argumento é undefined, e não quando é null. Essa é uma diferença sutil em relação ao ??, que trata os dois casos da mesma forma.

index.js
Output
Click Run to see the output here.

Se quiser que null também dispare o valor padrão, use ?? dentro do corpo:

index.js
Output
Click Run to see the output here.

Distinção pequena, mas fácil de escorregar quando uma API te devolve null significando "sem valor definido".

Quando usar o ??

Use o ?? como seu operador padrão, a não ser que tenha um motivo específico para não usar. Ele é o que reflete melhor como os dados costumam se comportar na prática — 0, '' e false geralmente são valores legítimos que você quer preservar, e só dados realmente ausentes merecem um fallback. Deixe o || para os casos em que você de fato quer substituir qualquer valor falsy.

A seguir: classes

Com isso, fechamos objetos e arrays — agora você tem as ferramentas para montar e navegar por estruturas de dados com segurança. O próximo capítulo muda o foco para organizar comportamento: classes, herança e o sistema de protótipos que sustenta tudo isso.

Perguntas frequentes

O que é o operador nullish coalescing no JavaScript?

O ?? retorna o operando da direita apenas quando o operando da esquerda é null ou undefined. Caso contrário, ele devolve o valor da esquerda sem alterar nada. valor ?? fallback é a forma recomendada de definir um padrão sem cair em armadilhas com valores falsy válidos, como 0 ou ''.

Qual a diferença entre ?? e || no JavaScript?

O || usa o fallback para qualquer valor falsy — 0, '', false, NaN, null, undefined. Já o ?? só entra em ação com null e undefined. Se 0 ou uma string vazia forem valores legítimos nos seus dados, vá de ??. Agora, se a ideia é realmente rejeitar todos os valores falsy, o || continua sendo a escolha certa.

Dá para combinar nullish coalescing com optional chaining?

Dá sim, e essa dupla é super comum. user?.settings?.theme ?? 'light' percorre a cadeia com segurança, devolve undefined se algo no meio do caminho não existir e, então, aplica 'light' como padrão. Os dois operadores foram lançados juntos no ES2020 justamente pensando nesse uso.

Para que serve o operador ??= ?

a ??= b atribui b a a somente quando a está como null ou undefined. É a atribuição lógica nullish — um atalho para a = a ?? b, mas com short-circuit: se a já tem valor, o lado direito nem chega a ser avaliado. Muito útil para preencher defaults que faltam em um objeto de opções.

Aprenda a programar com o Coddy

COMEÇAR