javascript-operador-encadenamiento-opcional

Operador encadenamiento opcional `?.` en JavaScript

El operador de encadenamiento opcional (?.) nos permite acceder a propiedades y métodos de objetos de manera segura cuando el objeto que tiene la propiedad puede ser null o undefined.

Esto evita la necesidad de escribir múltiples comprobaciones condicionales para asegurar que cada nivel de la cadena de acceso esté definido.

Antes de la introducción del operador de encadenamiento opcional en JavaScript, teníamos que verificar manualmente si cada propiedad existía antes de intentar acceder a la siguiente.

El operador ?. es muy útil, y simplifica enormemente nuestro código (y ya sabéis, más simple, es más legible y mantenible).

Sintaxis básica

La sintaxis básica del operador de encadenamiento opcional es la siguiente:

const resultado = objeto?.propiedad;

En este caso,

  • Si objeto tiene un valor definido, se accederá a propiedad de manera normal.
  • Si objeto es null o undefined, resultado será undefined y no se lanzará un error.

Veamos un ejemplo práctico para entender mejor cómo funciona el operador de encadenamiento opcional:

let usuario = {
  nombre: 'Juan',
  direccion: 'Una casa bonita'
};

let codigoPostal = usuario?.direccion?.codigoPostal;
let codigoPostal = usuario?.producto?.codigoBarras;
console.log(codigoPostal); // Resultado: '12345'

En este ejemplo,

  • Accedemos a la propiedad direccion del objeto usuario.
  • Como esta propiedad existe, obtendremos el valor ‘Una casa bonita’.

Por otro lado,

  • También accedemos a producto.codigoBarras (que no existe)
  • Sin embargo, en lugar de tirar una excepción, simplemente obtendremos undefined.

Encadenamiento Múltiple

El operador de encadenamiento opcional también puede usarse con otro encadenamiento múltiple. Esto nos permite hacer “cadenetas” seguras

let resultado = objeto?.propiedad1?.subpropiedad?.otrasubpropiedad;

Por ejemplo,

const usuario = {
  perfil: {
    direccion: {
      ciudad: 'Madrid'
    }
  }
};

const ciudad = usuario.perfil?.direccion?.ciudad;

console.log(ciudad); // 'Madrid'

Si usuario.perfil o usuario.perfil.direccion fueran null o undefined, ciudad sería undefined, evitando un error al intentar acceder a una propiedad de un objeto no definido.

Uso con métodos

El operador de encadenamiento opcional también se puede usar para invocar métodos que podrían no estar definidos:

const resultado = objeto?.metodo?.();

Aquí, si objeto o metodo son null o undefined, no se lanzará un error y resultado será undefined. Si ambos están definidos, se invocará metodo.

Por ejemplo

const persona = {
  nombre: 'Ana',
  saludar: () => 'Hola'
};

const saludo = persona.saludar?.();
console.log(saludo); // 'Hola'

Si persona.saludar fuera null o undefined, no se intentaría invocar el método y saludo sería undefined.

Acceso a elementos de Arrays

Aunque menos común, el operador de encadenamiento opcional también se puede usar para acceder a elementos de arrays:

const usuarios = [{ nombre: 'Carlos' }, null, { nombre: 'Sofia' }];
const primerNombre = usuarios[0]?.nombre;
const segundoNombre = usuarios[1]?.nombre;
const tercerNombre = usuarios[2]?.nombre;

console.log(primerNombre); // 'Carlos'
console.log(segundoNombre); // undefined
console.log(tercerNombre); // 'Sofia'

Combinación con operador de coalescencia nula ??

El operador de encadenamiento opcional se puede combinar con el operador de coalescencia nula (??) para proporcionar valores predeterminados:

const usuario = {};
const nombre = usuario.perfil?.nombre ?? 'Nombre predeterminado';
console.log(nombre); // 'Nombre predeterminado'

Aquí, nombre será 'Nombre predeterminado' si usuario.perfil es undefined o null.

Comparación con otras técnicas de acceso

Uso de Condiciones &&

Antes del encadenamiento opcional, era común utilizar condiciones && para evitar errores de acceso en objetos anidados:

const ciudad = usuario && usuario.perfil && usuario.perfil.direccion && usuario.perfil.direccion.ciudad;

Este enfoque es menos legible y más propenso a errores. El operador de encadenamiento opcional simplifica esta sintaxis

const ciudad = usuario?.perfil?.direccion?.ciudad;

Evitad usar && para esto. Es terrible. Usar ?., que para eso está 😉

Uso de operador ternario

El operador ternario también se puede usar para comprobar si los niveles intermedios están definidos:

const ciudad = usuario ? (usuario.perfil ? (usuario.perfil.direccion ? usuario.perfil.direccion.ciudad : undefined) : undefined) : undefined;

Sin embargo, este método no hay Dios que lea eso es más complejo y menos legible en comparación con el operador de encadenamiento opcional.

¡Que no hagáis eso! 😆

Limitaciones del operador encadenamiento opcional

No evita asignaciones

El operador de encadenamiento opcional no puede usarse para asignaciones. Solo se puede utilizar para acceder a propiedades y métodos:

objeto?.propiedad = valor; // Esto generará un error

No detecta todos los errores

El encadenamiento opcional solo evita errores relacionados con una propiedad o método no definido. No maneja otros tipos de errores que puedan surgir en el acceso a propiedades o métodos:

const resultado = objeto?.metodo()?.propiedad;

Es decir, evidentemente, si al llamar a metodo() tu programa ha explotado, ?. no te protege de ello (no gestiona excepciones, no es un try-catch).