Ao contrário de muitas outras linguagens, existem duas entidades diferentes em JavaScript que representam a ausência de um valor (significativo). São null e undefined.
O valor primitivo null é usado como um "valor vazio" intencional para uma variável.
Em outras linguagens, uma construção parecida pode ser usada apenas para objetos (ausentes) ou tipos de ponteiro.
Em JavaScript, null representa em geral um valor vazio para qualquer tipo.
let name = null;
// name is intentionally set to "empty" because it is not
// available
Você pode verificar se uma variável é null usando o operador de igualdade estrita ===.
Embora null seja um valor primitivo, o operador typeof retorna object "incorretamente", por razões históricas.
Isso significa que ele não pode ser usado sozinho para verificar se uma variável é null.
let name = null;
name === null;
// => true
// Pitfall:
typeof name;
// => 'object'
Uma variável à qual não foi atribuído um valor é do tipo
undefined.1
Isso significa que, enquanto null representa um valor vazio (mas ainda um valor), undefined representa a ausência total de um valor. 🤯
undefined aparece em contextos diferentes.
undefined.undefined.undefined.undefined, a menos que esse argumento tenha um valor padrão.let name;
console.log(name);
// => undefined
let obj = { greeting: 'hello world' };
console.log(obj.missingKey);
// => undefined
function returnNothing() {
return;
}
console.log(returnNothing());
// => undefined
Você pode verificar se uma variável é undefined usando o operador de igualdade estrita === ou o operador typeof.
let name;
name === undefined;
// => true
typeof name === 'undefined';
// => true
Não é recomendado atribuir undefined manualmente a uma variável. Em vez disso, use sempre null para deixar claro que você definiu um valor vazio de propósito.
Como mencionado acima, acessar uma chave inexistente em um objeto retorna undefined em JavaScript.
No entanto, se você tenta obter um valor aninhado e a chave pai não existe, a avaliação da chave aninhada é feita sobre undefined e leva a TypeError: Cannot read property ... of undefined.
Na teoria, você sempre precisaria verificar se a chave pai existe antes de tentar obter a chave aninhada.
Isso era feito muitas vezes com o operador AND &&, mas, para valores profundamente aninhados, isso leva a expressões muito longas.
obj.level1 && obj.level1.level2 && obj.level1.level2.level3;
Para resolver esse problema, o encadeamento opcional foi adicionado à especificação da linguagem em 2020.
Com o operador de encadeamento opcional ?., você pode garantir que o JavaScript só tente acessar a chave aninhada se a chave pai não for null nem undefined.
Caso contrário, undefined é retornado.
const obj = {
address: {
street: 'Trincomalee Highway',
city: 'Batticaloa',
},
};
obj.residence;
// => undefined
obj.address.zipCode;
// => undefined
obj.residence.street;
// => TypeError: Cannot read property 'street' of undefined
obj.residence?.street;
// => undefined
obj.residence?.street?.number;
// => undefined
Existem situações em que você quer aplicar um valor padrão caso uma variável seja null ou undefined.
No passado, isso era feito muitas vezes com um operador ternário ? ou aproveitando a avaliação preguiçosa do operador OR ||.
Isso tem a desvantagem de que o valor padrão é aplicado em todos os casos em que a variável é falsy (por exemplo, '' ou 0), não apenas quando ela é null ou undefined.
Isso pode facilmente causar resultados inesperados.
let amount = null;
amount = amount || 1;
// => 1
amount = 0;
amount = amount || 1;
// => 1
amount = 0;
amount ? amount : 1;
// => 1
Para resolver isso, o operador de coalescência nula ?? foi introduzido.
Assim como o encadeamento opcional, ele foi adicionado à especificação da linguagem em 2020.
O operador de coalescência nula ?? retorna o operando do lado direito apenas quando o operando do lado esquerdo é null ou undefined.
Caso contrário, o operando do lado esquerdo é retornado.
Com isso, agora é possível aplicar um valor padrão de forma mais específica.
let amount = null;
amount = amount ?? 1;
// => 1
amount = 0;
amount = amount ?? 1;
// => 0
[1] Undefined, MDN. (2021). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined (acessado em 4 de junho de 2021).