Menu

Destructuring en JavaScript: objetos, arrays y más

Cómo funciona el destructuring en JavaScript: extraer valores de objetos y arrays, renombrar variables, valores por defecto, patrones anidados y parámetros de función.

Desestructuración en JavaScript: pattern matching sobre la forma de los datos

La desestructuración en JavaScript te permite escribir un patrón que imita la forma de un objeto o un array, y extraer valores por nombre o por posición en una sola línea. En vez de ir accediendo propiedad por propiedad, describes lo que quieres y JavaScript te lo entrega.

Existen dos variantes:

index.js
Output
Click Run to see the output here.

Las llaves hacen match con un objeto por nombre de propiedad. Los corchetes, con un array por posición. En ambos casos, las variables que aparecen antes del = son declaraciones nuevas: no estás accediendo por índice al valor, estás describiendo un patrón que extrae las piezas.

Antes de que existiera el destructuring, el mismo código se veía así:

const name = user.name;
const age = user.age;
const first = scores[0];
const second = scores[1];

No es el fin del mundo, pero se vuelve repetitivo cuando lo haces en cada función.

Desestructuración de objetos: se usan los nombres de las propiedades

Al desestructurar objetos, los nombres dentro de las llaves tienen que coincidir con las propiedades del objeto original. El orden da igual: JavaScript las busca por clave.

index.js
Output
Click Run to see the output here.

Si la propiedad no existe en el objeto, la variable queda como undefined (sin lanzar ningún error):

index.js
Output
Click Run to see the output here.

Ese comportamiento silencioso del undefined es algo que conviene tener muy presente, porque una errata en el nombre de una propiedad puede dejarte rascándote la cabeza a las 2 de la mañana.

Renombrar variables al desestructurar

A veces el nombre de la propiedad del objeto no es el que quieres usar como variable: quizá choca con otra cosa que ya tienes en ese ámbito, o la API usa una convención de nombres que no te termina de convencer. Para estos casos, usa la sintaxis original: nuevoNombre para renombrarla:

index.js
Output
Click Run to see the output here.

Se lee así: "toma la propiedad id y llámala userId". Primero va el nombre de la propiedad y después el nombre de la nueva variable, separados por dos puntos. A simple vista parece una anotación de tipo como las de otros lenguajes, pero no lo es.

Valores por defecto en destructuring

Si una propiedad podría no existir, asígnale un valor por defecto directamente en el patrón:

index.js
Output
Click Run to see the output here.

Los valores por defecto solo se aplican cuando el valor es undefined. En cambio, null, 0 y "" pasan tal cual, sin ser reemplazados:

index.js
Output
Click Run to see the output here.

Ese detalle pilla a más de uno. Si quieres que null también dispare el valor por defecto, tienes que hacer la comprobación a mano, o tirar del operador de coalescencia nula ?? después del destructuring.

También puedes combinar valores por defecto con renombrado:

index.js
Output
Click Run to see the output here.

La desestructuración de arrays se basa en la posición

Los arrays no tienen nombres, solo índices, así que el patrón hace la correspondencia por posición. Usa comas para saltarte los elementos que no te interesen:

index.js
Output
Click Run to see the output here.

Las dos comas iniciales le dicen a JavaScript: "sáltate los índices 0 y 1". Visualmente queda un poco denso, pero resulta muy útil cuando solo te interesa un valor del medio.

El destructuring de arrays brilla de verdad con funciones que devuelven varios valores a la vez:

index.js
Output
Click Run to see the output here.

El mismo patrón aparece por todas partes en los hooks de React: const [count, setCount] = useState(0).

Rest en destructuring: recogiendo lo que sobra

Dentro de un patrón de desestructuración, ...nombre agrupa en una variable nueva todo lo que no se haya asignado ya por nombre o por posición.

En arrays, el rest se queda con la cola:

index.js
Output
Click Run to see the output here.

En objetos, el rest recoge todas las propiedades que no hayas nombrado de forma explícita:

index.js
Output
Click Run to see the output here.

Esta es la forma idiomática de quitar un campo de un objeto sin mutarlo: rest es un objeto nuevo que contiene todo excepto id.

El rest tiene que ir al final del patrón. const [...init, last] es un error de sintaxis.

Destructuring anidado en JavaScript

Los patrones se pueden anidar. Si una propiedad es a su vez un objeto o un array, puedes desestructurarla dentro de la misma expresión:

index.js
Output
Click Run to see the output here.

Es potente, pero úsalo con cabeza. Tres niveles de llaves anidadas empiezan a parecer un rompecabezas. Cuando llegues ahí, extrae valores intermedios en sus propias variables: la legibilidad manda sobre la astucia.

Un detalle que pilla a mucha gente: data: { user } dentro del patrón no crea una variable llamada data. Es una instrucción que dice "métete dentro de data y sigue desestructurando". Si necesitas data en sí, añádelo aparte:

index.js
Output
Click Run to see the output here.

Desestructuración en parámetros de función

El sitio donde más vas a usar destructuring en JavaScript es, sin duda, en los parámetros de una función. De un plumazo, conviertes el clásico "pásale un objeto de opciones" en una firma que se documenta sola:

index.js
Output
Click Run to see the output here.

Desde quien llama, parece una llamada normal con un objeto de opciones. Pero dentro de la función tienes variables con nombre y valores por defecto, y te ahorras todo ese options.name || "default" de siempre.

Ojo con un detalle: si llamas a esta función sin argumentos, revienta, porque no se puede desestructurar undefined. La solución es darle un valor por defecto al parámetro completo:

index.js
Output
Click Run to see the output here.

El = {} que va tras el patrón dice: "si no llega ningún argumento, hazte a la idea de que era un objeto vacío". A partir de ahí, los valores por defecto internos toman el control.

Intercambiar y reasignar variables

El destructuring también funciona con variables ya declaradas, pero necesitas envolver el patrón del objeto entre paréntesis (de lo contrario, JavaScript interpreta el { como el inicio de un bloque):

index.js
Output
Click Run to see the output here.

El intercambio con arrays queda limpísimo. Reasignar propiedades de objetos ya es menos común, pero el truco de los paréntesis conviene tenerlo guardado para cuando haga falta.

Un ejemplo realista

Juntando casi todo lo anterior, veamos una función que procesa la respuesta de una API:

index.js
Output
Click Run to see the output here.

Cada capa desestructurada tiene su valor por defecto, así que la función aguanta datos incompletos sin llenarse de if a la defensiva. Ese es el verdadero premio: firmas precisas y tolerantes a la vez.

Siguiente paso: spread de objetos

La desestructuración saca valores de los objetos. El spread hace lo contrario: los mete dentro, ya sea para copiar, combinar o sobrescribir. En el JavaScript moderno van siempre de la mano, y ahora le toca el turno al spread.

Preguntas frecuentes

¿Qué es el destructuring en JavaScript?

El destructuring (o asignación por desestructuración) es una sintaxis que permite extraer valores de objetos o arrays y asignarlos a variables en un solo paso. Por ejemplo, const { name } = user; toma la propiedad name de user, y const [first, second] = list; coge los dos primeros elementos de list. Es un patrón a la izquierda del = que imita la forma del valor de la derecha.

¿Cómo se renombra una variable al hacer destructuring?

Con la sintaxis { original: nuevoNombre }. Por ejemplo, const { name: username } = user; extrae la propiedad name de user y la asigna a una variable local llamada username. Ojo, que se confunde fácilmente con una anotación de tipo: recuerda que primero va el nombre de la propiedad y, después de los dos puntos, el nombre de la nueva variable.

¿Se pueden definir valores por defecto con destructuring?

Sí. const { timeout = 5000 } = options; usará 5000 si options.timeout es undefined. Los valores por defecto solo se aplican cuando el valor es undefined: null, 0 o '' pasan tal cual sin ser sustituidos. También puedes combinar defaults con renombrado: const { t: timeout = 5000 } = options;.

¿Cuál es la diferencia entre destructuring y spread?

Parecen lo mismo pero hacen justo lo contrario. El destructuring (const { a, b } = obj) saca valores de una estructura. El spread (const copy = { ...obj }) mete valores dentro de una estructura nueva. Y cuando ves ... dentro de un patrón de destructuring, eso es un rest pattern: recoge los elementos sobrantes en una variable nueva.

Aprende a programar con Coddy

COMENZAR