A diferencia de muchos otros lenguajes, en JavaScript existen dos entidades distintas que representan la ausencia de un valor (significativo): null y undefined.
El valor primitivo null se usa como un «valor vacío» intencional para una variable.
En otros lenguajes, una construcción similar podría usarse solo para objetos (faltantes) o tipos de puntero.
En JavaScript, null generalmente representa un valor vacío para cualquier tipo.
let name = null;
// name is intentionally set to "empty" because it is not
// available
Puedes verificar si una variable es null usando el operador de igualdad estricta ===.
Aunque null es un valor primitivo, el operador typeof devuelve object «incorrectamente» por razones históricas.
Eso significa que no se puede usar por sí solo para verificar si una variable es null.
let name = null;
name === null;
// => true
// Pitfall:
typeof name;
// => 'object'
Una variable a la que no se le ha asignado un valor es de tipo
undefined.1
Esto significa que, mientras que null representa un valor vacío (pero aún un valor), undefined representa la ausencia total de un valor. 🤯
undefined aparece en distintos contextos.
undefined.undefined.undefined.undefined, a menos que ese argumento tenga un valor predeterminado.let name;
console.log(name);
// => undefined
let obj = { greeting: 'hello world' };
console.log(obj.missingKey);
// => undefined
function returnNothing() {
return;
}
console.log(returnNothing());
// => undefined
Puedes verificar si una variable es undefined usando el operador de igualdad estricta === o el operador typeof.
let name;
name === undefined;
// => true
typeof name === 'undefined';
// => true
No se recomienda asignar undefined manualmente a una variable; en su lugar, usa siempre null para dejar claro que estableciste un valor vacío de forma intencional.
Como se mencionó antes, acceder a una clave que no existe en un objeto devuelve undefined en JavaScript.
Sin embargo, si intentas obtener un valor anidado y la clave padre no existe, la evaluación de la clave anidada se realiza sobre undefined y provoca TypeError: Cannot read property ... of undefined.
En teoría, siempre tendrías que verificar que la clave padre exista antes de intentar obtener la clave anidada.
Esto se hacía a menudo con el operador AND &&, pero para valores muy anidados da lugar a expresiones muy largas.
obj.level1 && obj.level1.level2 && obj.level1.level2.level3;
Para resolver este problema, el encadenamiento opcional se añadió a la especificación del lenguaje en 2020.
Con el operador de encadenamiento opcional ?. puedes asegurarte de que JavaScript solo intente acceder a la clave anidada si la clave padre no era null ni undefined.
De lo contrario, se devuelve 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
Hay situaciones en las que quieres aplicar un valor predeterminado en caso de que una variable sea null o undefined.
En el pasado, esto se hacía a menudo con un operador ternario ? o aprovechando la evaluación diferida del operador OR ||.
Esto tiene la desventaja de que el valor predeterminado se aplica en todos los casos en los que la variable es falsy (por ejemplo, '' o 0), no solo cuando es null o undefined.
Esto puede causar fácilmente resultados inesperados.
let amount = null;
amount = amount || 1;
// => 1
amount = 0;
amount = amount || 1;
// => 1
amount = 0;
amount ? amount : 1;
// => 1
Para solucionar esto, se introdujo el operador de coalescencia nula ??.
Al igual que el encadenamiento opcional, se añadió a la especificación del lenguaje en 2020.
El operador de coalescencia nula ?? devuelve el operando del lado derecho solo cuando el operando del lado izquierdo es null o undefined.
De lo contrario, se devuelve el operando del lado izquierdo.
Con esto, ahora se puede aplicar un valor predeterminado de forma más 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 el 4 de junio de 2021).