W3docs

Operador de Fusión Nula en JavaScript (??)

Aprende el operador de fusión nula (??) de JavaScript, cómo difiere de ||, reglas de precedencia y los operadores de asignación lógica ??=, &&= y ||=.

El operador de fusión nula (??) es una forma concisa y expresiva de proporcionar un valor predeterminado en JavaScript. Devuelve su operando derecho solo cuando el operando izquierdo es nulo — es decir, null o undefined — y en caso contrario devuelve el valor izquierdo sin modificarlo. Introducido en ES2020, resuelve un problema histórico con el uso del operador || para valores predeterminados, y funciona en conjunto con el encadenamiento opcional y los operadores lógicos que ya conoces.

Qué Significa "Nulo"

Un valor se considera nulo cuando es exactamente null o undefined. Cualquier otro valor — incluyendo los falsos como 0, '', false y NaN — es tratado como un valor real e intencional por ??.

null ?? 'default'       // 'default'
undefined ?? 'default'  // 'default'

0 ?? 'default'          // 0
'' ?? 'default'         // ''
false ?? 'default'      // false
NaN ?? 'default'        // NaN

La regla es simple: si el lado izquierdo es null o undefined, obtienes el lado derecho; de lo contrario obtienes el lado izquierdo.

javascript— editable

Cómo Difiere ?? de ||

Esta es la razón más importante por la que existe ??. El operador OR lógico (||) devuelve el lado derecho siempre que el lado izquierdo sea cualquier valor falso — 0, '', false, NaN, null y undefined todos cuentan. Ese comportamiento está bien hasta que 0 o una cadena vacía es un valor legítimo, momento en el que || produce silenciosamente el resultado incorrecto.

Considera un contador cuyo valor válido puede ser 0:

let count = 0;

let withOr = count || 100;   // 100  — ¡incorrecto! 0 fue reemplazado
let withNullish = count ?? 100; // 0   — correcto, 0 fue preservado

Dado que 0 es falso, || lo trata igual que "sin valor" y recurre a 100. El operador ?? reconoce que 0 no es nulo y lo conserva. La misma trampa se aplica a las cadenas vacías:

javascript— editable
Advertencia

Usa ?? en lugar de || siempre que 0, '' o false sean entradas válidas. Usar || para valores predeterminados en esos casos es una de las fuentes más comunes de errores sutiles en JavaScript — por ejemplo, una cantidad de 0 convirtiéndose en 1, o un campo de búsqueda vacío tomando un texto de marcador de posición.

Precedencia y Paréntesis

El operador ?? tiene baja precedencia — aproximadamente el mismo nivel que || y menor que los operadores aritméticos y de comparación. En la práctica, esto significa que el valor de reserva se resuelve antes de que el valor se use en una expresión más grande, pero aun así deberías agrupar con paréntesis para mantener la intención clara.

let height = null;
let width;

// Each ?? is evaluated, then the products are multiplied
let area = (height ?? 100) * (width ?? 50);
console.log(area); // 100 * 50 = 5000

Sin los paréntesis, la multiplicación vincularía más estrechamente de lo que podrías esperar, por lo que envolver cada valor predeterminado en ( ... ) mantiene la operación sin ambigüedades y legible.

Combinar ?? Con && o || Está Prohibido

JavaScript deliberadamente no permite mezclar ?? con && o || en la misma expresión sin paréntesis. Hacerlo es un SyntaxError, porque la precedencia entre ellos sería ambigua y fácil de malinterpretar.

// SyntaxError: Unexpected token '||'
let result = a ?? b || c;

// Fix it by grouping explicitly:
let safe = (a ?? b) || c;   // valid
let other = a ?? (b || c);  // also valid, different meaning

Las dos formas válidas significan cosas diferentes, razón por la cual el lenguaje te obliga a elegir. Añade los paréntesis y establece con precisión lo que pretendes.

Nota

La restricción solo se aplica cuando ?? aparece directamente junto a && o ||. Puedes usarlos libremente en expresiones separadas, y los paréntesis siempre resuelven la ambigüedad.

Operadores de Asignación Lógica

ES2021 añadió tres operadores de asignación lógica que combinan una asignación con una verificación lógica. Asignan a la variable del lado izquierdo solo cuando se cumple una condición, lo que los hace perfectos para establecer valores predeterminados y actualizaciones condicionales.

Asignación Nula (??=)

x ??= y asigna y a x solo si x es actualmente null o undefined. Es la forma de asignación de ?? y la más común de las tres para establecer valores predeterminados en un object.

let settings = { theme: 'dark' };

settings.theme ??= 'light';   // already set → stays 'dark'
settings.fontSize ??= 16;     // missing → becomes 16

console.log(settings); // { theme: 'dark', fontSize: 16 }

Asignación OR Lógico (||=)

x ||= y asigna y a x cuando x es falso (0, '', false, null, undefined, NaN). Al igual que ||, puede sobrescribir valores falsos válidos, así que úsalo solo cuando cualquier valor falso realmente signifique "reemplázame".

javascript— editable

Asignación AND Lógico (&&=)

x &&= y asigna y a x solo cuando x es verdadero. Es útil para actualizar un valor que ya existe sin crearlo.

let config = { token: 'abc123' };

config.token &&= config.token.trim(); // truthy → trimmed and reassigned
config.missing &&= 'never set';        // undefined → left untouched

console.log(config); // { token: 'abc123' }

Cada operador también cortocircuita: solo evalúa y asigna el lado derecho cuando la condición lo requiere, por lo que los efectos secundarios del lado derecho se omiten cuando la asignación no ocurre.

Usos en el Mundo Real

El operador ?? brilla en cualquier lugar donde un valor pueda legítimamente estar ausente mientras que 0 o '' deben ser respetados. Los escenarios típicos incluyen leer configuraciones, establecer valores predeterminados para parámetros de función opcionales y extraer campos de respuestas API.

// 1. Default options merged with user input
function createButton(options) {
  let label = options.label ?? 'Submit';
  let count = options.count ?? 0; // 0 stays 0, never becomes a default
  return { label, count };
}

// 2. Reading a possibly-missing API field
let response = { data: { user: { nickname: null } } };
let name = response.data.user.nickname ?? 'Guest';
console.log(name); // 'Guest'

Funciona especialmente bien con el encadenamiento opcional (?.). El encadenamiento opcional devuelve undefined de forma segura cuando parte de una ruta está ausente, y ?? entonces proporciona el valor de reserva en una sola línea limpia:

let city = user?.address?.city ?? 'Unknown';

Esto se lee como: "Usa la ciudad del usuario si toda la cadena existe, de lo contrario usa 'Unknown'." Para decidir cuál de dos rutas tomar basándose en una condición, el operador condicional (ternario) sigue siendo la mejor herramienta — ?? es específicamente para proporcionar valores predeterminados para valores nulos.

Información

Soporte de navegadores: ?? es parte de ES2020 y los operadores de asignación lógica (??=, ||=, &&=) llegaron en ES2021. Todos los navegadores modernos y Node.js 14+ los admiten. Si debes apuntar a entornos muy antiguos, un transpilador como Babel puede compilarlos.

Resumen

  • ?? devuelve el operando derecho solo cuando el izquierdo es null o undefined; de lo contrario devuelve el izquierdo.
  • Prefiere ?? sobre || para valores predeterminados cuando 0, '' o false son valores válidos.
  • ?? tiene baja precedencia — agrupa con paréntesis, y nunca lo coloques directamente junto a && o || sin paréntesis (eso es un SyntaxError).
  • ??=, ||= y &&= asignan condicionalmente: en nulo, en falso y en verdadero respectivamente.
  • Combina ?? con el encadenamiento opcional (?.) para leer datos posiblemente ausentes y establecer un valor predeterminado en una sola expresión.

Pon a Prueba tu Conocimiento

Práctica
¿A qué valor se evalúa la expresión 0 ?? 100?
¿A qué valor se evalúa la expresión 0 ?? 100?
Práctica
¿Por qué escribir a ?? b || c sin paréntesis es un problema?
¿Por qué escribir a ?? b || c sin paréntesis es un problema?
Práctica
¿Qué hace user.role ??= 'member' cuando user.role es undefined?
¿Qué hace user.role ??= 'member' cuando user.role es undefined?
Was this page helpful?