DEV Community

Paulo Elienay II
Paulo Elienay II

Posted on

Valores null e undefined no JavaScript

Lidar com dados pode vir a ser caótico. Muitas vezes existe um grande dinamismo na forma como vamos recebê-los e valores nulos e não definidos podem ser comuns em alguns projetos. Veja como lidar com eles.

Primeiro, vamos ver os erros que podem ser causados.

Acessando um valor não definido no JavaScript

let bubble = gum;
Enter fullscreen mode Exit fullscreen mode

O código acima irá retornar o erro Uncaught ReferenceError: gum is not defined (gum não foi definida) pois estamos tentando criar a variável bubble com o valor da variável gum, que nunca tinha sido criada antes.

No TypeScript

let bubble = gum;
Enter fullscreen mode Exit fullscreen mode
TSError: ⨯ Unable to compile TypeScript:
index.ts:1:14 - error TS2304: Cannot find name 'gum'.

1 let bubble = gum;
               ~~~
Enter fullscreen mode Exit fullscreen mode

No TypeScript recebemos uma mensagem de erro igualmente útil que nos mostra exatamente onde estamos errados e o que fazer para arrumar o erro.

Acessando um valor nulo no JavaScript

let empresa = {
  nome: "Enviadores de Cotonetes",
  dono: null
}

console.log(empresa.dono.nome);
Enter fullscreen mode Exit fullscreen mode

Rodando o código acima teremos outro tipo de erro retornado; Uncaught TypeError: can't access property "algo", empresa.algo is undefined. Pode ter sido imaginado que nós iríamos ter o mesmo erro, pois estávamos criando outro erro de referência como nos exemplos anteriores mas nós antes recebemos um erro no tipo da variável que estamos tentando acessar. "empresa.dono não pode ter nada pois é nula" vem antes de "empresa.dono.nome não existe".

Arrumando o erro

Agora que sabemos exatamente que erro nosso código anterior estava causando, é só uma questão de fazer testes o suficiente para que ele não ocorra, certo?

let empresa = {
  nome: "Enviadores de Cotonetes",
  dono: null
}

if (empresa != null
    && empresa.dono != null
    && empresa.dono.nome != null) {
  console.log(empresa.dono.nome)
} else {
  console.warn("Empresa, dono ou nome do dono da empresa não existe.")
}
Enter fullscreen mode Exit fullscreen mode

Depende. Muito. Embora o código acima rode sem retornar erros, ele já está muito verboso antes mesmo de termos uma checagem robusta (não é possível saber se apenas o dono é null ou apenas o nome do dono é null). E criar todos os testes iria criar algo mais verboso ainda.

let empresa = {
  nome: "Enviadores de Cotonetes",
  dono: null
}

if (empresa === null) {
  console.warn("Empresa não existe.")
} else if (empresa.dono === null) {
  console.warn("Dono da empresa não existe.")
} else {
  console.log(empresa.dono.nome) // -> irá retornar `undefined`
}
Enter fullscreen mode Exit fullscreen mode

Embora horrendo, o código acima está checando tudo o que nós precisamos que ele cheque. Por sorte geralmente não escrevemos testes assim e a nossa linguagem nos dá uma forma mais elegante de lidar com isso.

Optional chaining

let empresa = {
  nome: "Enviadores de Cotonetes",
  dono: null
}

console.log(empresa?.dono?.nome) // -> irá retornar `undefined`
Enter fullscreen mode Exit fullscreen mode

Certo. O que está acontecendo no código acima? É bem simples. Imagine que toda vez que você está acessando algo dentro de um objeto (usando o . como em empresa.dono), você está fazendo isso acreditando que o valor anterior não é nullish (null ou undefined). Vemos isso no código que eu chamei de horrendo. Eu só usei empresa.dono após um if que checava que empresa não era nullish. É como se eu estivesse deixando a opção aberta de que esse valor pode vir a ser nullish. E é isso que que optional chaining (?.) faz. Pense nele como uma pergunta. "O valor da esquerda é nullish? Não? Então prossiga". Isso faz com que nós não recebamos nenhum tipo de erro, nem de tipo nem de referência, pois já estamos adicionando a possibilidade do valor ser nulo na mesma linha que chamamos a variável.

E os testes?

Os testes dos objetos pai não são mais necessários e nós podemos seguir em frente com a lógica de negócios.

let empresa = {
  nome: "Enviadores de Cotonetes",
  dono: null
}

if (empresa?.dono?.nome != null) {
  console.log(`O nome do dono da empresa é ${empresa.dono.nome}.`)
} else {
  console.warn("Nome do dono da empresa não existe.")
}
Enter fullscreen mode Exit fullscreen mode

Discussion (0)