Aprende a usar el operador optional chaining (?.) para evitar errores al acceder a propiedades que pueden no existir
midudev
Más clases y directos en YouTube
Optional Chaining
Cuando trabajamos con el DOM, a veces un elemento puede no existir. Si intentamos acceder a métodos o propiedades de un elemento que es null, obtenemos un error. El optional chaining (?.) nos ayuda a evitar estos errores.
El problema: Elementos que no existen
Imagina que intentamos seleccionar un botón que no está en la página:
<!DOCTYPE html><html lang="es"> <head> <script type="module"> const button = document.querySelector('#boton-importante') button.addEventListener('click', function () { console.log('Click') }) </script> </head> <body> <h1>Mi página</h1> <!-- ❌ No hay ningún botón con id="boton-importante" --> </body></html>
❌ Error:
Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
¿Por qué falla?
const button = document.querySelector('#boton-importante')console.log(button) // null// Intentamos hacer null.addEventListener()button.addEventListener('click', function () { /* ... */})// ❌ Error: No puedes llamar métodos en null
Solución tradicional: Verificar con if
La forma tradicional es verificar si el elemento existe antes de usarlo:
const button = document.querySelector('#boton-importante')if (button) { button.addEventListener('click', function () { console.log('Click en el botón') })}
✅ Ahora funciona:
- Si
buttonexiste → Se añade el evento - Si
buttonesnull→ No hace nada (no hay error)
Ejemplo con múltiples verificaciones:
const button = document.querySelector('#boton-importante')if (button) { button.addEventListener('click', function () { console.log('Click') })}const input = document.querySelector('#mi-input')if (input) { input.addEventListener('input', function () { console.log('Escribiendo...') })}const form = document.querySelector('#mi-formulario')if (form) { form.addEventListener('submit', function (event) { event.preventDefault() })}
Problema: Mucho código repetitivo con los if.
Optional Chaining: La solución moderna
El optional chaining (?.) es un operador que verifica automáticamente si algo existe antes de acceder a sus propiedades o métodos.
Sintaxis:
objeto?.propiedadobjeto?.metodo()
¿Cómo funciona?
const button = document.querySelector('#boton-importante')// Con optional chainingbutton?.addEventListener('click', function () { console.log('Click')})
Comportamiento:
- Si
buttonexiste (no esnullniundefined) → EjecutaaddEventListener - Si
buttonesnulloundefined→ No hace nada (no hay error)
Comparación: Con y sin optional chaining
Sin optional chaining:
const button = document.querySelector('#boton-importante')if (button) { button.addEventListener('click', function () { console.log('Click') })}
Con optional chaining:
const button = document.querySelector('#boton-importante')button?.addEventListener('click', function () { console.log('Click')})
Resultado: Exactamente el mismo comportamiento, pero con menos código.
Optional chaining con propiedades
No solo funciona con métodos, también con propiedades:
const button = document.querySelector('#boton-importante')// Acceder a propiedadesconsole.log(button?.textContent) // undefined si no existeconsole.log(button?.id) // undefined si no existeconsole.log(button?.disabled) // undefined si no existe// Cambiar propiedadesbutton?.classList.add('activo')button?.setAttribute('data-applied', 'true')
Optional chaining encadenado
Puedes usar ?. múltiples veces en cadena:
const container = document.querySelector('#container')// Acceder a propiedades anidadas de forma seguraconst width = container?.firstChild?.getBoundingClientRect()?.widthconsole.log(width) // undefined si cualquier parte es null
Sin optional chaining:
let widthif (container) { if (container.firstChild) { const rect = container.firstChild.getBoundingClientRect() if (rect) { width = rect.width } }}console.log(width)