?. y ?? — Sintaxis esencial de JavaScript
Al finalizar este tema
Comprenderá por qué aparecen ?. y ??, y podrá evitar los errores que se producen debido a undefined.
La respuesta de la API llega, pero falla
Se recibe la información del usuario desde el servidor:
const user = await fetch('/api/user').then(r => r.json());
console.log(user.address.city);Funciona correctamente. Sin embargo, algunos usuarios no han registrado su dirección. user.address es undefined.
TypeError: Cannot read properties of undefined (reading 'city')Todos los desarrolladores de JavaScript se han encontrado con este error. Si no sabes qué es undefined e intentas acceder a sus propiedades, fallará.
La forma antigua: el infierno de las sentencias if
let city;
if (user && user.address && user.address.city) {
city = user.address.city;
} else {
city = 'no_registrado';
}El movimiento funciona. Sin embargo, al aumentar la profundidad, se produce lo siguiente:
if (user && user.company && user.company.department && user.company.department.manager && user.company.department.manager.name) {
// ...
}No se puede leer.
Encadenamiento opcional — ?.
const city = user?.address?.city;Eso es todo. ?. "se detiene y devuelve undefined si el lado izquierdo es null o undefined". No genera un error.
user?.address?.city
// user es null/undefined → devuelve undefined (sin error)
// user.address es null/undefined → devuelve undefined (sin error)
// si ambos existen → devuelve el valor de cityTambién se puede utilizar en las llamadas a métodos:
user?.getProfile?.();
// si getProfile no existe, devuelve undefined en lugar de errorTambién en los índices de la matriz:
const first = users?.[0]?.name;Coalescencia de valores nulos — ??
Se utiliza ?? cuando se desea proporcionar un valor predeterminado si ?. devuelve un valor nulo:
const city = user?.address?.city ?? 'no_registrado';Si el valor de "city" es nulo o no está definido, se mostrará "no registrado". Eso es todo.
"¿Entonces, en qué se diferencia de ||?" — Existe una diferencia muy importante:
const count = 0;
console.log(count || 10); // 10 — ¡0 es falsy!
console.log(count ?? 10); // 0 — 0 no es null/undefined| Valor | || (OR) | ?? (Nullish) |
|---|---|---|
null | Usa el valor predeterminado | Usa el valor predeterminado |
undefined | Usa el valor predeterminado | Usa el valor predeterminado |
0 | Usa el valor predeterminado | Conserva el valor original |
'' (cadena vacía) | Usa el valor predeterminado | Conserva el valor original |
false | Usa el valor predeterminado | Conserva el valor original |
|| filtra todos los valores "falsy" (0, '', false, null, undefined), mientras que ?? filtra solo null e undefined. Cuando 0 o una cadena vacía son valores válidos, se debe usar ??.
Combinación práctica
// analizar la respuesta de la API de forma segura
const userName = response?.data?.user?.name ?? 'anónimo';
const age = response?.data?.user?.age ?? 0;
const tags = response?.data?.user?.tags ?? [];
// acceder al DOM de forma segura
document.querySelector('.header')?.classList.add('active');
// llamar al callback de forma segura
config.onSuccess?.(result);Consideraciones importantes
No abuse de ?.. Si coloca ?. en todas partes, no podrá rastrear dónde se produce un valor nulo:
// Mala práctica — se tragan los errores
const value = a?.b?.c?.d?.e?.f ?? 'default';
// Aquí apareció 'default', pero ¿desde dónde era nulo??. solo debe usarse en contextos donde "podría no existir". Es adecuado para respuestas de API, configuraciones opcionales, consultas del DOM y otros casos donde realmente podría no haber un valor.
Conceptos clave
?.devuelveundefineden lugar de generar un error cuando el valor esnulloundefined. "Acceso seguro".??aplica valores predeterminados solo cuando el valor esnulloundefined. A diferencia de||, conserva los valores0y''. Combinación de ambos:user?.address?.city ?? 'No registrado'— este es el patrón básico en JavaScript moderno.