Ao contrário de muitas outras linguagens, existem em JavaScript duas entidades diferentes que representam a ausência de um valor (com significado).
Existem o null e o undefined.
O valor primitivo null é usado como um «valor vazio» intencional para uma variável.
Noutras linguagens, uma construção semelhante pode ser usada apenas para objetos (em falta) ou tipos de ponteiro.
Em JavaScript, o null representa geralmente um valor vazio para qualquer tipo.
let name = null;
// name is intentionally set to "empty" because it is not
// available
Podes verificar se uma variável é null com o operador de igualdade estrita ===.
Embora o null seja um valor primitivo, o operador typeof devolve object «erradamente», por razões históricas.
Isso significa que 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
Isto significa que, enquanto o null representa um valor vazio (mas ainda um valor), o undefined representa a ausência total de um valor. 🤯
O undefined aparece em contextos diferentes.
undefined.undefined.undefined.undefined, a menos que esse argumento tenha um valor predefinido.let name;
console.log(name);
// => undefined
let obj = { greeting: 'hello world' };
console.log(obj.missingKey);
// => undefined
function returnNothing() {
return;
}
console.log(returnNothing());
// => undefined
Podes verificar se uma variável é undefined com o operador de igualdade estrita === ou o operador typeof.
let name;
name === undefined;
// => true
typeof name === 'undefined';
// => true
Não é recomendado atribuir undefined a uma variável manualmente; usa antes null, para deixar claro que definiste um valor vazio de forma intencional.
Como referido acima, aceder a uma chave inexistente num objeto devolve undefined em JavaScript.
No entanto, se tentares obter um valor aninhado e a chave mãe não existir, a avaliação da chave aninhada é feita sobre undefined e origina TypeError: Cannot read property ... of undefined.
Teoricamente, terias sempre de verificar se a chave mãe existe antes de poderes tentar obter a chave aninhada.
Isto era feito frequentemente com o operador E &&, mas para valores profundamente aninhados dá origem a expressões muito longas.
obj.level1 && obj.level1.level2 && obj.level1.level2.level3;
Para resolver este problema, o encadeamento opcional foi adicionado à especificação da linguagem em 2020.
Com o operador de encadeamento opcional ?., podes garantir que o JavaScript só tenta aceder à chave aninhada se a chave mãe não for null nem undefined.
Caso contrário, é devolvido undefined.
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
Há situações em que queres aplicar um valor predefinido caso uma variável seja null ou undefined.
No passado, isto era feito frequentemente com um operador ternário ? ou recorrendo à avaliação preguiçosa do operador OU ||.
Isto tem a desvantagem de o valor predefinido ser aplicado em todos os casos em que a variável é falsy (por exemplo, '' ou 0), e não apenas quando é null ou undefined.
Isto 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 isto, foi introduzido o operador de coalescência nula ??.
Tal como o encadeamento opcional, foi adicionado à especificação da linguagem em 2020.
O operador de coalescência nula ?? devolve o operando do lado direito apenas quando o operando do lado esquerdo é null ou undefined.
Caso contrário, é devolvido o operando do lado esquerdo.
Assim, um valor predefinido pode agora ser aplicado 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 (consultado a 4 de junho de 2021).