Llevas tres lecciones usando esta sintaxis de refilón y con una nota al pie que decía «esto se explica en 04-06». Ha llegado el momento. const [eliminada] = tareas.splice(i, 1), for (const [i, tarea] of backlog.entries()), par[0] y par[1] recorriendo Object.entries: todos esos casos son la misma idea, y la idea se llama desestructuración. Consiste en desempaquetar los elementos de un array en variables con nombre, en una sola línea y sin índices. Parece un detalle cosmético y no lo es: cambia la legibilidad de los bucles con índice, permite intercambiar variables sin auxiliar, hace que los parámetros de una función se lean solos y es la base de patrones que verás en React y en casi cualquier código moderno. En esta lección la aprenderás completa, y la aplicarás a partir una fechaLimite ISO y a procesar los pares clave-valor del resumen por responsable de Taller Nómada.
Contenido
- Qué es desestructurar
- La sintaxis básica
- Saltar elementos con comas
- Valores por defecto
- El resto con
... - Intercambiar variables sin auxiliar
- Desestructurar en los parámetros de una función
- Arrays anidados
- Desestructurar el resultado de
split() - Desestructurar
Object.entries() - Desestructuración en
for...of - El patrón
[error, valor]y sus límites - Errores Comunes y Consejos
- Ejercicios
- Conclusión
- Qué es desestructurar
Mira estas dos formas de sacar los elementos de un array a variables:
const posicion = ['Iván', 25, 3];
// A mano, con índices
const responsableA = posicion[0];
const horasA = posicion[1];
const tareasA = posicion[2];
// Con desestructuración
const [responsable, horas, tareas] = posicion;
console.log(responsable, horas, tareas); // Iván 25 3La segunda versión hace exactamente lo mismo en una línea. La regla es sencilla:
Cuando en el lado izquierdo de una asignación pones un patrón entre corchetes, JavaScript no crea un array: desempaqueta el array de la derecha, elemento a elemento, en las variables que hayas nombrado, por posición.
El punto clave es ese: por posición, no por nombre. Los nombres de las variables los eliges tú libremente; lo que manda es el orden.
const [a, b, c] = ['Iván', 25, 3];
console.log(a); // 'Iván' ← el nombre da igual, cuenta la posiciónEsta es la diferencia esencial con la desestructuración de objetos, que estudiarás en la lección siguiente y que funciona al revés: allí manda el nombre y el orden es irrelevante.
- La sintaxis básica
const etiquetas = ['carpintería', 'compras', 'urgente'];
// Todas las variables que quieras, en orden
const [primera, segunda, tercera] = etiquetas;
console.log(primera); // 'carpintería'
// Puedes coger menos elementos de los que hay: el resto se ignora
const [soloLaPrimera] = etiquetas;
console.log(soloLaPrimera); // 'carpintería'
// Si pides más de los que hay, sobran undefined
const [x, y, z, w] = etiquetas;
console.log(w); // undefinedFunciona igual con let, con const y con variables ya declaradas:
let responsable;
let horas;
[responsable, horas] = ['Lucía', 14]; // sin declaración
console.log(responsable, horas); // Lucía 14Cuidado con esa última forma. Si la línea anterior no termina en punto y coma, JavaScript puede interpretar los corchetes como un acceso a índice (es uno de los casos de ASI que viste en 01-04). Cuando desestructures sobre variables existentes, empieza la línea con
;o asegúrate de cerrar la anterior.
Y funciona con cualquier iterable, no solo con arrays: strings, Set, Map…
const [primeraLetra, segundaLetra] = 'Nómada';
console.log(primeraLetra, segundaLetra); // N ó
const [uno, dos] = new Set([10, 20, 30]);
console.log(uno, dos); // 10 20
- Saltar elementos con comas
Si solo te interesan algunas posiciones, deja el hueco vacío con una coma:
const fila = ['Iván', 'alta', 'en-curso', 12, '2026-09-30'];
// Quiero el responsable y las horas: salto tres posiciones
const [persona, , , horasEstimadas] = fila;
console.log(persona, horasEstimadas); // Iván 12
// Solo el estado (tercera posición)
const [, , estado] = fila;
console.log(estado); // 'en-curso'Cuenta las comas con cuidado: [, , estado] tiene dos comas antes del nombre, así que estado recoge la tercera posición. Es una sintaxis compacta pero fácil de contar mal; si necesitas saltar más de dos posiciones, suele ser más legible acceder por índice o replantear el dato como objeto.
- Valores por defecto
Cuando una posición no existe (o vale undefined), puedes indicar un valor por defecto con =, exactamente igual que en los parámetros de una función (03-03):
const [titulo, responsable = 'sin asignar', revisor = null] = ['Revisar la guillotina'];
console.log(titulo); // 'Revisar la guillotina'
console.log(responsable); // 'sin asignar' ← la posición 1 no existía
console.log(revisor); // nullEl detalle crítico, el mismo de los parámetros por defecto: el valor por defecto solo se aplica con undefined, no con null, ni con 0, ni con ''.
const [a = 'defecto'] = [null];
console.log(a); // null ← null NO activa el defecto
const [b = 'defecto'] = [undefined];
console.log(b); // 'defecto'
const [c = 10] = [0];
console.log(c); // 0 ← 0 tampoco lo activaEs la misma distinción que separa ?? de || (01-06), y por el mismo motivo. Si necesitas que null también active el valor por defecto, desestructura primero y aplica ?? después.
Los valores por defecto pueden ser expresiones, y solo se evalúan si hacen falta:
function fechaDeHoy() {
console.log(' (calculando la fecha...)');
return '2026-09-20';
}
const [titulo1, fecha1 = fechaDeHoy()] = ['Tarea A', '2026-10-01'];
// no imprime nada: la posición 1 existía
const [titulo2, fecha2 = fechaDeHoy()] = ['Tarea B'];
// (calculando la fecha...)
console.log(fecha2); // '2026-09-20'
- El resto con
...
...El elemento resto (rest element) recoge en un array nuevo todo lo que quede sin asignar:
const cola = ['Cartelería', 'Camisetas', 'Bolsas de tela', 'Reimpresión'];
const [siguiente, ...enEspera] = cola;
console.log(siguiente); // 'Cartelería'
console.log(enEspera); // [ 'Camisetas', 'Bolsas de tela', 'Reimpresión' ]
// Sirve también para separar cabecera y cuerpo
const [primera, segunda, ...resto] = cola;
console.log(resto); // [ 'Bolsas de tela', 'Reimpresión' ]Tres reglas del elemento resto:
- Debe ir el último.
const [...todo, ultimo] = cola;es unSyntaxError. - Siempre produce un array, aunque no quede nada: entonces será
[], nuncaundefined. - No admite valor por defecto:
[...resto = []]no es válido.
Y una aplicación muy útil, copiar sin el primero, que es lo que hace una cola:
function atender(cola) {
const [atendido, ...pendientes] = cola;
return { atendido, pendientes }; // no muta la cola original
}
const resultado = atender(cola);
console.log(resultado.atendido); // 'Cartelería'
console.log(resultado.pendientes.length); // 3
console.log(cola.length); // 4 ✓ intactaCompáralo con cola.shift(), que hace lo mismo pero mutando el array (04-03). Esta versión es inmutable, que es la línea de diseño del proyecto.
- Intercambiar variables sin auxiliar
El truco más celebrado de la desestructuración. Antes había que usar una variable temporal:
let a = 'Iván';
let b = 'Marta';
// A la antigua
let temporal = a;
a = b;
b = temporal;
// Con desestructuración: una línea, sin auxiliar
[a, b] = [b, a];
console.log(a, b); // Iván Marta (vuelven a su sitio)Funciona porque el lado derecho se evalúa entero antes de asignar: se construye el array ['Marta', 'Iván'] y solo entonces se reparte. Sirve también para elementos de un array:
const orden = ['T1', 'T2', 'T3'];
[orden[0], orden[2]] = [orden[2], orden[0]];
console.log(orden); // [ 'T3', 'T2', 'T1' ]Y para rotar tres o más valores de golpe:
- Desestructurar en los parámetros de una función
Si una función recibe un array, puedes desempaquetarlo en la propia firma. El parámetro deja de llamarse «ese array» y pasa a nombrar sus partes:
// Sin desestructurar: hay que recordar qué significa cada índice
function describirFilaA(fila) {
return `${fila[0]}: ${fila[1]} h`;
}
// Desestructurando en la firma: se lee solo
function describirFila([persona, horas]) {
return `${persona}: ${horas} h`;
}
console.log(describirFila(['Iván', 25])); // 'Iván: 25 h'Admite valores por defecto y resto, igual que fuera:
function resumirCola([siguiente = 'nada', ...resto] = []) {
return `Siguiente: ${siguiente}. En espera: ${resto.length}`;
}
console.log(resumirCola(['Cartelería', 'Camisetas'])); // 'Siguiente: Cartelería. En espera: 1'
console.log(resumirCola([])); // 'Siguiente: nada. En espera: 0'
console.log(resumirCola()); // 'Siguiente: nada. En espera: 0'Ese = [] final es importante: sin él, llamar a resumirCola() sin argumentos lanzaría un TypeError, porque no se puede desestructurar undefined. Es la misma protección que verás en 04-07 con el truco = {}.
Donde más se nota es en los callbacks de los métodos que estudiaste en 04-05:
const carga = { 'Iván': 25, 'Marta': 6, 'Lucía': 14 };
// Sin desestructurar: par[0] y par[1] no dicen nada
Object.entries(carga).forEach((par) => console.log(`${par[0]}: ${par[1]} h`));
// Desestructurando en el parámetro del callback: legible
Object.entries(carga).forEach(([persona, horas]) => console.log(`${persona}: ${horas} h`));
// Iván: 25 h
// Marta: 6 h
// Lucía: 14 h
- Arrays anidados
El patrón de la izquierda puede reproducir cualquier estructura, todo lo profunda que haga falta:
const semana = [
['lunes', [8, 6]],
['martes', [7, 5]]
];
const [[dia, [manana, tarde]]] = semana;
console.log(dia, manana, tarde); // lunes 8 6Léelo de fuera hacia dentro: el [[...]] exterior dice «coge el primer elemento de semana»; dentro, [dia, [manana, tarde]] dice «ese elemento es un array de dos: el primero se llama dia, y el segundo es a su vez un array de dos, manana y tarde».
Es potente, pero se vuelve ilegible enseguida. Regla práctica: más de dos niveles de anidamiento y probablemente el dato debería ser un objeto. Compara:
// Difícil de leer
const [[, [horasManana]]] = semana;
// El mismo dato modelado como objeto: no hace falta contar corchetes
const semanaObj = [{ dia: 'lunes', manana: 8, tarde: 6 }];
console.log(semanaObj[0].manana); // 8
- Desestructurar el resultado de
split()
split()Aquí llega la aplicación directa al proyecto. split(separador) parte un string en un array, y ese array es candidato perfecto para desestructurar. El caso canónico: partir una fechaLimite ISO.
const fechaLimite = '2026-09-30';
const [anio, mes, dia] = fechaLimite.split('-');
console.log(anio, mes, dia); // 2026 09 30
console.log(typeof anio); // 'string' ← split siempre devuelve stringsConvirtiendo a número sobre la marcha con map (04-04):
const [a, m, d] = fechaLimite.split('-').map(Number);
console.log(a, m, d); // 2026 9 30
console.log(typeof a); // 'number'Con esto ya puedes escribir una función de presentación que Marta lleva pidiendo desde el Módulo 1: mostrar la fecha en formato español.
const MESES = ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio',
'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'];
function fechaLegible(iso) {
const [anio, mes, dia] = iso.split('-');
return `${Number(dia)} de ${MESES[Number(mes) - 1]} de ${anio}`;
}
console.log(fechaLegible('2026-09-30')); // '30 de septiembre de 2026'
console.log(fechaLegible('2026-09-05')); // '5 de septiembre de 2026'
console.log(fechaLegible('2026-11-05')); // '5 de noviembre de 2026'Fíjate en MESES[Number(mes) - 1]: el -1 es porque los meses van de 1 a 12 y los índices del array de 0 a 11. Es el clásico desajuste de uno, y aquí está aislado en una sola línea fácil de revisar.
Otro uso frecuente, partir una línea de texto en campos:
const linea = 'Iván;alta;12;2026-09-30';
const [responsable, prioridad, horas, fecha] = linea.split(';');
console.log(`${responsable} tiene ${horas} h de prioridad ${prioridad}`);
// Iván tiene 12 h de prioridad altaUn aviso: si el string no tiene todos los separadores esperados, las variables sobrantes quedan undefined sin ningún error. Cuando proceses datos que vienen de fuera, combina la desestructuración con valores por defecto y una validación.
const [r = 'desconocido', p = 'media', h = '0'] = 'Lucía'.split(';');
console.log(r, p, h); // Lucía media 0
- Desestructurar
Object.entries()
Object.entries()Object.entries (04-01) devuelve un array de pares [clave, valor]. Desestructurarlos es lo que convierte un recorrido críptico en uno legible.
const carga = { 'Iván': 25, 'Marta': 6, 'Lucía': 14 };
// Sin desestructurar
for (const par of Object.entries(carga)) {
console.log(`${par[0]} lleva ${par[1]} h`);
}
// Desestructurando: nombres en lugar de índices
for (const [persona, horas] of Object.entries(carga)) {
console.log(`${persona} lleva ${horas} h`);
}
// Iván lleva 25 h
// Marta lleva 6 h
// Lucía lleva 14 hCombinado con los métodos de 04-05, el resultado es directamente el bloque «carga por persona» del informe semanal:
Object.entries(carga)
.toSorted(([, horasA], [, horasB]) => horasB - horasA) // desestructurando y saltando la clave
.forEach(([persona, horas], i) => console.log(`${i + 1}. ${persona}: ${horas} h`));
// 1. Iván: 25 h
// 2. Lucía: 14 h
// 3. Marta: 6 hMerece la pena detenerse en la comparadora: ([, horasA], [, horasB]) => horasB - horasA. Los dos parámetros son pares, y en cada uno saltamos la clave con una coma para quedarnos solo con el valor. Comparado con (a, b) => b[1] - a[1], la versión desestructurada dice qué se compara, no en qué posición está.
El camino de vuelta también existe: Object.fromEntries reconstruye un objeto a partir de pares.
const cargaEnJornadas = Object.fromEntries(
Object.entries(carga).map(([persona, horas]) => [persona, Number((horas / 8).toFixed(1))])
);
console.log(cargaEnJornadas); // { Iván: 3.1, Marta: 0.8, Lucía: 1.8 }
- Desestructuración en
for...of
for...ofYa lo has visto en la lección 04-04 con una nota al pie. Ahora entiendes exactamente qué ocurre:
for (const [indice, tarea] of backlog.entries()) {
console.log(`${indice + 1}. ${tarea.titulo}`);
}
// 1. Rediseñar la sala polivalente
// 2. Cartelería del taller de serigrafía
// ...backlog.entries() produce, en cada vuelta, un array de dos elementos: [0, {tarea 1}], [1, {tarea 2}]… El patrón const [indice, tarea] desempaqueta ese par en el momento. Y como sigue siendo un for...of, conserva break y continue, que era la razón de preferirlo a forEach:
for (const [i, tarea] of backlog.entries()) {
if (tarea.estado === 'hecha') continue;
if (i >= 3) break;
console.log(`${i}: ${tarea.titulo}`);
}También funciona recorriendo arrays de arrays directamente:
const asignaciones = [['Iván', 12], ['Marta', 6], ['Lucía', 14]];
for (const [persona, horas] of asignaciones) {
console.log(`${persona} → ${horas} h`);
}Y con Map, que produce pares de forma natural (04-05):
const conteo = new Map([['Iván', 3], ['Marta', 2], ['Lucía', 1]]);
for (const [persona, tareas] of conteo) {
console.log(`${persona}: ${tareas} tarea(s)`);
}
- El patrón
[error, valor] y sus límites
[error, valor] y sus límitesEn 03-03 estudiaste cómo devolver varios valores de una función. Una de las opciones era devolver un array, y ahora la desestructuración hace que esa opción resulte cómoda: el patrón [error, valor], popular en muchas bibliotecas.
/**
* Valida una tarea. Devuelve [error, tarea]:
* si va bien, error es null; si va mal, tarea es null.
*/
function validarTarea(tarea) {
if (typeof tarea.titulo !== 'string' || tarea.titulo.trim() === '') {
return ['El título es obligatorio.', null];
}
if (!(tarea.horasEstimadas > 0 && tarea.horasEstimadas <= 40)) {
return ['Las horas deben estar entre 0 y 40.', null]; // R3
}
return [null, tarea];
}
const [error, tareaValida] = validarTarea({ titulo: 'Revisar la guillotina', horasEstimadas: 2 });
if (error) {
console.log(`✗ ${error}`);
} else {
console.log(`✓ ${tareaValida.titulo}`);
}
// ✓ Revisar la guillotina
const [error2] = validarTarea({ titulo: '', horasEstimadas: 2 });
console.log(error2); // 'El título es obligatorio.'Su virtud es que quien llama elige los nombres, lo que evita colisiones cuando haces varias llamadas seguidas:
const [errorA, tareaA] = validarTarea(candidataA);
const [errorB, tareaB] = validarTarea(candidataB);Ahora los límites, porque conviene saber cuándo no usarlo:
Devolver un array [error, valor] |
Devolver un objeto { error, valor } |
|
|---|---|---|
| Nombres | Los pone quien llama | Los pone la función (se pueden renombrar, 04-07) |
| Orden | Significativo: equivocarlo es un bug silencioso | Irrelevante |
| Coger solo el segundo | const [, valor] = ... (coma incómoda) |
const { valor } = ... |
| Añadir un tercer dato | Rompe a quien contaba posiciones | No rompe nada |
| Autodocumentación | Baja: hay que leer la función | Alta |
El bug silencioso de la segunda fila es real y muy fácil de cometer:
const [tarea, error] = validarTarea({ titulo: 'Algo', horasEstimadas: 2 });
// ✗ Están al revés: tarea vale null y error vale el objeto tarea.
// No hay ningún aviso. El programa simplemente hace lo contrario de lo que crees.Regla práctica: usa el array de dos elementos cuando los dos valores sean inseparables y evidentes (un resultado y su error, una coordenada, un par clave-valor), y siempre que quien llame vaya a querer poner nombres propios. Para tres o más datos, o cuando los nombres importen, devuelve un objeto, como hacía resumirCarga() en 03-03. Es la misma recomendación de aquella lección, ahora con las dos sintaxis en la mano para compararlas.
Errores Comunes y Consejos
1. Confundir posición con nombre. En arrays manda el orden. const [titulo, id] = [1, 'Rediseñar...'] asigna titulo = 1. Con objetos (04-07) manda el nombre.
2. Desestructurar undefined o null.
const [a] = undefined; // ✗ TypeError: undefined is not iterable
const [b] = null; // ✗ TypeError
const [c] = []; // ✓ c es undefined, sin errorProtégete con = [] en los parámetros o con ?? [] en el valor.
3. Contar mal las comas al saltar elementos. [, , estado] coge la tercera posición. Si dudas, cuenta las comas: hay tantas posiciones saltadas como comas antes del nombre.
4. Poner el resto en medio. const [...todo, ultimo] = a; es un SyntaxError. El resto va siempre el último.
5. Esperar que el valor por defecto actúe con null. Solo actúa con undefined. Si null también debe activar el defecto, aplica ?? después.
6. Olvidar el punto y coma en la línea anterior al desestructurar sobre variables ya declaradas: [a, b] = [b, a] puede unirse a la línea de arriba y producir un error confuso.
7. Desestructurar un Set esperando un orden concreto. Funciona porque es iterable, pero el orden es el de inserción; no lo uses para «coger los dos menores».
Consejo profesional. Desestructura cuando mejore la lectura, no por deporte. const [a, , , , , f] = fila; no es mejor que fila[5]. La señal de que estás forzándola es tener que contar comas: si tu dato necesita nombres, probablemente debería ser un objeto, y la lección siguiente te dará la sintaxis exacta para desempaquetarlo.
Ejercicios
Ejercicio 1 — La fecha, por partes. Escribe una función desglosarFecha(iso) que reciba una fechaLimite en formato 'yyyy-mm-dd' y devuelva un objeto { anio, mes, dia, legible }, donde anio, mes y dia sean números y legible tenga el formato '30 de septiembre de 2026'. Después escribe mismoMes(isoA, isoB), que devuelva true si dos fechas caen en el mismo año y mes. Pruébalas con '2026-09-30', '2026-09-05' y '2026-11-05'.
Ejercicio 2 — Podio de carga. Partiendo del objeto const carga = { 'Iván': 25, 'Marta': 6, 'Lucía': 14 };, escribe podio(carga) que devuelva un objeto { primero, segundo, resto }, donde primero y segundo sean strings con el formato 'Iván (25 h)' y resto sea un array con el mismo formato para los demás. Usa Object.entries, toSorted con desestructuración en la comparadora, y desestructuración con elemento resto.
Ejercicio 3 — Cola del taller de serigrafía, inmutable. Escribe tres funciones que no muten el array de entrada:
atenderSiguiente(cola)→ devuelve[atendido, colaRestante].adelantar(cola, posicion)→ devuelve una cola nueva con el encargo de esa posición colocado el primero.intercambiar(cola, i, j)→ devuelve una cola nueva con dos posiciones intercambiadas, usando desestructuración.
Pruébalas con ['Cartelería', 'Camisetas', 'Bolsas de tela', 'Reimpresión'].
Soluciones
Ejercicio 1
const MESES = ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio',
'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'];
function desglosarFecha(iso) {
const [anio, mes, dia] = iso.split('-').map(Number);
return { anio, mes, dia, legible: `${dia} de ${MESES[mes - 1]} de ${anio}` };
}
function mismoMes(isoA, isoB) {
const [anioA, mesA] = isoA.split('-');
const [anioB, mesB] = isoB.split('-');
return anioA === anioB && mesA === mesB;
}
console.log(desglosarFecha('2026-09-30'));
// { anio: 2026, mes: 9, dia: 30, legible: '30 de septiembre de 2026' }
console.log(desglosarFecha('2026-09-05').legible); // '5 de septiembre de 2026'
console.log(mismoMes('2026-09-30', '2026-09-05')); // true
console.log(mismoMes('2026-09-30', '2026-11-05')); // falseDos observaciones. En desglosarFecha, el .map(Number) convierte las tres partes de golpe, y eso hace que dia sea 5 en lugar de '05' —justo lo que queremos para el texto legible—. En mismoMes, en cambio, no convertimos: comparar los strings '09' con '09' funciona perfectamente y ahorra la conversión. Fíjate también en { anio, mes, dia, ... }: escribir anio en lugar de anio: anio es la abreviatura de propiedad, que la lección siguiente explicará junto al resto de la sintaxis de objetos.
Ejercicio 2
function podio(carga) {
const [primero, segundo, ...resto] = Object.entries(carga)
.toSorted(([, horasA], [, horasB]) => horasB - horasA)
.map(([persona, horas]) => `${persona} (${horas} h)`);
return { primero, segundo, resto };
}
console.log(podio({ 'Iván': 25, 'Marta': 6, 'Lucía': 14 }));
// { primero: 'Iván (25 h)', segundo: 'Lucía (14 h)', resto: [ 'Marta (6 h)' ] }
console.log(podio({ 'Iván': 25 }));
// { primero: 'Iván (25 h)', segundo: undefined, resto: [] }La cadena hace tres cosas encadenadas de 04-05 —convertir a pares, ordenar y transformar en texto— y la desestructuración de la primera línea reparte el resultado en un solo gesto. El segundo console.log muestra el comportamiento en el caso límite: segundo queda undefined y resto queda [] (nunca undefined), tal como decía la regla del apartado 5. Si quisieras un texto en lugar de undefined, bastaría con const [primero, segundo = '—', ...resto].
Ejercicio 3
function atenderSiguiente(cola) {
const [atendido, ...colaRestante] = cola;
return [atendido, colaRestante];
}
function adelantar(cola, posicion) {
if (posicion < 0 || posicion >= cola.length) return cola.slice();
const copia = cola.slice();
const [elegido] = copia.splice(posicion, 1);
copia.unshift(elegido);
return copia;
}
function intercambiar(cola, i, j) {
const copia = cola.slice();
[copia[i], copia[j]] = [copia[j], copia[i]];
return copia;
}
const cola = ['Cartelería', 'Camisetas', 'Bolsas de tela', 'Reimpresión'];
const [atendido, restante] = atenderSiguiente(cola);
console.log(atendido); // 'Cartelería'
console.log(restante); // [ 'Camisetas', 'Bolsas de tela', 'Reimpresión' ]
console.log(adelantar(cola, 3));
// [ 'Reimpresión', 'Cartelería', 'Camisetas', 'Bolsas de tela' ]
console.log(intercambiar(cola, 0, 3));
// [ 'Reimpresión', 'Camisetas', 'Bolsas de tela', 'Cartelería' ]
console.log(cola);
// [ 'Cartelería', 'Camisetas', 'Bolsas de tela', 'Reimpresión' ] ✓ intacta en las tresLas tres respetan la regla del proyecto: copiar antes de modificar. atenderSiguiente ni siquiera necesita copiar, porque el elemento resto ya crea un array nuevo. adelantar combina slice (copiar), splice con desestructuración (sacar y quedarse con lo sacado) y unshift (poner delante), los tres de 04-03. E intercambiar es el truco del apartado 6 aplicado a posiciones de un array; sin desestructuración necesitaría una variable temporal.
Conclusión
La desestructuración de arrays es una sintaxis pequeña con un impacto grande en la legibilidad. Sabes que desempaqueta por posición, que puedes saltar elementos con comas, dar valores por defecto que solo se activan con undefined, y recoger la cola con el elemento resto ..., que va siempre el último y siempre produce un array. Sabes intercambiar variables sin auxiliar, desestructurar directamente en los parámetros de una función —incluido el = [] que evita el error al llamar sin argumentos— y desempaquetar estructuras anidadas, con la advertencia de que a partir de dos niveles el dato probablemente pedía ser un objeto.
Y la has aplicado donde de verdad se nota: partiendo una fechaLimite ISO con split('-') para construir fechaLegible('2026-09-30') → '30 de septiembre de 2026'; recorriendo el resumen de carga por responsable con for (const [persona, horas] of Object.entries(carga)); escribiendo comparadoras que dicen qué comparan, ([, horasA], [, horasB]) => horasB - horasA; y entendiendo por fin, sin nota al pie, qué significa for (const [i, tarea] of backlog.entries()). También has visto el patrón [error, valor] y, sobre todo, sus límites frente a devolver un objeto: el orden es significativo, equivocarlo no da ningún aviso, y añadir un tercer dato rompe a quien contaba posiciones.
Ese límite es justo la puerta de entrada a la lección siguiente. Los datos de Nómada Tareas no son pares ni ternas: son tareas con nueve campos con nombre, y para ellas desempaquetar por posición no tiene ningún sentido. En Desestructuración de Objetos, Spread y Rest aprenderás la variante que manda por nombre, con renombrado y valores por defecto, escribirás por fin el objeto de opciones de 03-03 directamente en la firma de la función, y descubrirás el operador ... en su otra faceta —el spread—, que permite copiar y combinar objetos y, con ello, escribir la actualización inmutable { ...tarea, estado: 'hecha' } que es la base de todo el trabajo con estado en los frameworks modernos.
Curso de JavaScript: De Principiante a Avanzado
Módulo 1: Introducción a JavaScript
- ¿Qué es JavaScript?
- Configuración de tu Entorno de Desarrollo
- Tu Primer Programa en JavaScript
- Sintaxis y Conceptos Básicos de JavaScript
- Variables y Tipos de Datos
- Operadores Básicos
- Conversión de Tipos y Comparaciones
- El Proyecto del Curso: Nómada Tareas
Módulo 2: Estructuras de Control
- Sentencias Condicionales
- Bucles: for, while, do-while
- Sentencias Switch
- Control del Flujo: break, continue y Bucles Anidados
- Manejo de Errores con try-catch
Módulo 3: Funciones
- Definición y Llamada de Funciones
- Expresiones de Función y Funciones Flecha
- Parámetros y Valores de Retorno
- Ámbito y Closures
- Hoisting y el Contexto de Ejecución
- Funciones de Orden Superior
- Recursividad
Módulo 4: Objetos y Arrays
- Introducción a los Objetos
- Métodos de Objeto y la Palabra Clave
this - Arrays: Conceptos Básicos y Métodos
- Iteración sobre Arrays
- Buscar, Ordenar y Agregar Datos: find, sort y reduce
- Desestructuración de Arrays
- Desestructuración de Objetos, Spread y Rest
- JSON y Copias de Objetos
Módulo 5: Objetos y Funciones Avanzadas
- Prototipos y Herencia
- Clases y Programación Orientada a Objetos
- Encapsulación: Getters, Setters y Campos Privados
- Módulos e Importación/Exportación
- JavaScript Asíncrono: Callbacks
- Promesas y Async/Await
- El Bucle de Eventos y la Cola de Microtareas
- Iteradores y Generadores
Módulo 6: El Modelo de Objetos del Documento (DOM)
- Introducción al DOM
- Selección y Manipulación de Elementos del DOM
- Manejo de Eventos
- Propagación, Delegación y Eventos Personalizados
- Creación y Eliminación de Elementos del DOM
- Renderizado de Listas y Plantillas HTML
- Manejo y Validación de Formularios
Módulo 7: APIs del Navegador y Temas Avanzados
- Almacenamiento Local y de Sesión
- Fetch API y AJAX
- Peticiones Robustas: Errores, Timeouts y AbortController
- WebSockets
- Service Workers y Aplicaciones Web Progresivas (PWAs)
- APIs del Navegador Esenciales
- Introducción a WebAssembly
Módulo 8: Pruebas y Depuración
- Depuración de JavaScript
- Calidad de Código: ESLint, Prettier y Convenciones
- Pruebas Unitarias con Jest
- Dobles de Prueba: Mocks, Stubs y Spies
- Pruebas de Integración
- Pruebas de Extremo a Extremo con Cypress
Módulo 9: Rendimiento y Optimización
- Medir Antes de Optimizar: DevTools y Web Vitals
- Optimización del Rendimiento de JavaScript
- Gestión de Memoria
- Manipulación Eficiente del DOM
- Carga Perezosa y División de Código
Módulo 10: Frameworks y Librerías de JavaScript
- Por Qué Existen los Frameworks
- Introducción a React
- Gestión de Estado con Redux
- Conceptos Básicos de Vue.js
- Conceptos Básicos de Angular
- Elegir el Framework Adecuado
