Operador Nullish Coalescing

Aprende a usar el operador ?? en JavaScript


Aunque el título del artículo es el Nullish Coalescing, en este artículo vamos realmente a hablar de cuatro operadores diferentes, que tienen bastante relación entre sí:

Operador Nombre del operador Descripción
|| OR lógico Devuelve el primer valor que sea verdadero. Si son falsos, devuelve el segundo.
||= Asignación lógica Asigna el valor de la derecha a la variable de la izquierda (si es falso).
?? Nullish Coalescing Devuelve el valor de la izquierda si no es null ni undefined. Sino, el de la derecha.
??= Asignación nula Asigna el valor de la derecha a la variable de la izquierda (si es null o undefined).

Veamos sus características y profundicemos en ellos.

Operador OR lógico

El operador lógico OR (||) establece una condición donde devolverá el primer valor si es true o el segundo si el primero es false. Esto se puede leer de forma sencilla de la siguiente forma: «devuelve a (si es verdadero), o si no, b».

Veamos algunos ejemplos reales, primero con que es más sencillo de entender:

false || false     // false (si ninguno de los dos es true, false)
true || false      // true (desde que uno sea true, true)
false || true      // true (idem)
true || true       // true (idem)

Sin embargo, ten en cuenta que podemos utilizar este operador con otros tipos de datos y no sólo con . En el anterior, los valores repetidos no hay que diferenciarlos: si false || false te da igual que false devuelva, simplemente es false.

Esto no ocurre con otros tipos de datos. Recuerda que en programación, cualquier valor numérico superior a 0 es considerado true como y que cualquier valor que sea 0 o falsy, es false.

Veamos algunos ejemplos:

0 || false         // false (se evalua como false || false, devuelve el segundo)
0 || null          // null (se evalua como false || false, devuelve el segundo)
44 || undefined    // 44 (se evalua como true || false, devuelve el primero)
0 || 17            // 17 (se evalua como false || true, devuelve el segundo)
4 || 10            // 4 (se evalua como true || true, devuelve el primero)

Teniendo todo esto en cuenta, el operador || nos podría venir bastante bien para situaciones donde, por ejemplo, tenemos una variable name que no sabemos a ciencia cierta si está definida y queremos crear una nueva variable userName con el valor de name, o sino, un valor por defecto "Unknown name":

const userName = name || "Unknown name";

"Manz" || "Unknown name"      // "Manz"
null || "Unknown name"        // "Unknown name"
false || "Unknown name"       // "Unknown name"
undefined || "Unknown name"   // "Unknown name"
0 || "Unknown name"           // "Unknown name" (el 0 se evalua como falso)

OJO: Ten presente que en algunos casos te puede interesar esta funcionalidad, sólo que 0 es un valor válido que tiene sentido para ti. En ese caso, es mejor utilizar el operador de unión nula ?? (nullish coalescing) que explicaremos a continuación.

Asignación lógica

Igual que tenemos la posibilidad de realizar asignaciones como += que son la mezcla de una asignación con una operación de suma, también podemos hacer lo propio con el operador lógico de asignación ||=, que une un operador lógico con una asignación.

Observa el siguiente fragmento de código:

let userName = "";

if (!userName) {
  userName = "Manz";
}

Este código, podemos simplificarlo utilizando el operador lógico OR de asignación ||=:

let userName = "";      // o null, false o undefined

userName ||= "Manz"     // Ahora es "Manz"
userName ||= "Paco"     // Sigue siendo "Manz"
userName ||= false      // Sigue siendo "Manz"

Con ||= conseguimos que si el valor inicial de userName es un valor que se evalua como falso como null, undefined, 0, false o "", entonces realizará la asignación con el valor de la derecha. En caso contrario, si ya tiene un valor establecido que no es falso, no hará nada.

Operador Nullish coalescing

El operador nullish coalescing (unión nula) es un operador lógico muy similar al operador OR, pero con ciertos matices y diferencias. A grandes rasgos, se puede decir que el operador a ?? b devuelve b sólo cuando a es undefined o null.

Dicho de otra forma, funciona igual que el operador OR, pero sólo para valores que sean undefined o null, en lugar de la amplia gama de valores que se pueden evaluar como falso.

Veamoslo con un ejemplo para ver la diferencia con el anterior:

42 || 50          // 42
42 ?? 50          // 42 (ambos se comportan igual)

false || 50       // 50 (false es un valor falsy, devuelve el segundo)
false ?? 50       // false (la parte izquierda no es null ni undefined, devuelve el primero)

0 || 50           // 50 (0 es un valor falsy, devuelve el segundo)
0 ?? 50           // 0 (la parte izquierda no es null ni undefined, devuelve el primero)

null || 50        // 50 (null es un valor falsy, devuelve el segundo)
null ?? 50        // 50 (devuelve el segundo)

undefined || 50   // 50 (undefined es un valor falsy, devuelve el segundo)
undefined ?? 50   // 50 (devuelve el segundo)

Dependiendo del caso, podría interesarnos utilizar el operador ?? o el operador ||. Veamos un ejemplo algo diferente. Imagina que tenemos un objeto data donde tenemos almacenado la cantidad de balas que le quedan a un personaje de un videojuego.

Si necesitamos mostrar al usuario visualmente en el menú que se ha quedado sin balas, quizás nos podría interesar utilizar el operador ||. Por otro lado, si lo que queremos es mostrar el total numérico de balas, quizás nos interesaría más utilizar el operador ??.

const data = { ammo: 0 }
data.ammo || "Sin balas";     // "Sin balas"
data.ammo ?? "Sin balas";     // 0

const data = {}
data.ammo || "Sin balas";     // "Sin balas"
data.ammo ?? "Sin balas";     // "Sin balas"

Ten en cuenta que en el segundo caso, la propiedad ammo es undefined, ya que no está definida.

Asignación lógica nula

Al igual que pasó con el operador OR lógico, también tenemos una mezcla del nullish coalescing y una asignación. Este operador es bastante interesante para algunas operaciones muy frecuentes en Javascript.

Existen ciertos casos donde, si una variable tiene valores null o undefined (valores nullish) y sólo en esos casos, queremos cambiar su valor. Veamos como se haría sin utilizar la asignación lógica nula y como podríamos resumirlo utilizándola:

// Sin asignación lógica nula
if (x === null || x === undefined) {
  x = 50;
}

// Con asignación lógica nula
x ??= 50;

Como puedes ver, utilizando el operador ??= podemos simplificar mucho nuestro código. Recuerda que a ??= b es equivalente a a ?? (a = b). Esto puede ser super útil para simplificar casos como el siguiente:

const resetConfig = (data) => {
  data.life ??= 100;
  data.level ??= 1;
  return data;
}

resetConfig({ life: 25, level: 4 });      // { life: 25, level: 4 }
resetConfig({ life: null, level: 2 });    // { life: 100, level: 2 }
resetConfig({});                          // { life: 100, level: 1 }

Observa que la función resetConfig() obtiene un objeto por parámetro y en el caso de tener una de las propiedades life o level a null o no existir (o valer undefined), las reseteará al valor indicado.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev