Introduzione
Quando un’applicazione riceve dati da più fonti, spesso deve trasformarli prima di utilizzarli. Un prodotto può arrivare da un file JSON, da un database o da un servizio esterno con proprietà non uniformi. In questi casi, il codice rischia di diventare difficile da leggere se accede continuamente a proprietà annidate e costruisce nuovi oggetti manualmente.
Il destructuring assignment permette di estrarre rapidamente valori da oggetti e array. Gli operatori spread e rest, invece, consentono rispettivamente di espandere valori e raccogliere quelli rimanenti. In questo tutorial useremo queste funzionalità per creare una piccola pipeline che normalizza i dati di un catalogo prodotti, applica trasformazioni e produce un risultato pronto per la visualizzazione.
L’esempio è utile perché mostra un caso comune: ricevere dati con proprietà tecniche, rimuovere informazioni inutili, aggiungere valori calcolati e mantenere le funzioni indipendenti e riutilizzabili.
Codice completo
const prodottiRicevuti = [
{
id: 101,
title: "Tastiera meccanica",
price: 89.9,
currency: "EUR",
category: "accessories",
supplierData: {
internalCode: "KB-001",
warehouse: "Milano"
},
tags: ["meccanica", "gaming"],
dimensions: {
width: 45,
height: 3
}
},
{
id: 102,
title: "Monitor 27 pollici",
price: 249.5,
currency: "EUR",
category: "display",
supplierData: {
internalCode: "MN-027",
warehouse: "Roma"
},
tags: ["4k", "usb-c"],
dimensions: {
width: 62,
height: 37
}
}
];
// Rest raccoglie le proprietà che non ci interessano direttamente.
function rimuoviDatiTecnici({
supplierData,
dimensions,
...datiPubblici
}) {
return datiPubblici;
}
// Destructuring con valori predefiniti e alias.
function aggiungiInformazioni({
id,
title: nome,
price,
currency = "EUR",
tags = []
}) {
const prezzoFormattato = new Intl.NumberFormat("it-IT", {
style: "currency",
currency
}).format(price);
return {
id,
nome,
prezzo: price,
prezzoFormattato,
tags,
disponibile: price < 300
};
}
// Spread crea un nuovo oggetto senza modificare quello originale.
function normalizzaProdotto(prodotto) {
const datiSenzaMetadati = rimuoviDatiTecnici(prodotto);
const datiArricchiti = aggiungiInformazioni(datiSenzaMetadati);
return {
...datiSenzaMetadati,
...datiArricchiti,
tags: [...datiArricchiti.tags, "catalogo"]
};
}
const catalogo = prodottiRicevuti.map(normalizzaProdotto);
console.log(catalogo); Spiegazione
Estrarre e rinominare le proprietà
Nella funzione aggiungiInformazioni il parametro viene destrutturato direttamente nella firma:
function aggiungiInformazioni({
id,
title: nome,
price,
currency = "EUR",
tags = []
}) {
// ...
} La sintassi title: nome estrae la proprietà title, ma la rende disponibile nel corpo della funzione con il nome nome. Questo è utile quando il nome originale non è coerente con la convenzione usata dall’applicazione.
currency = "EUR" assegna un valore predefinito se la proprietà non esiste o vale undefined. La stessa tecnica viene utilizzata per tags, evitando controlli ripetitivi come prodotto.tags || [].
Usare rest per escludere proprietà
La funzione rimuoviDatiTecnici estrae due proprietà che non devono essere pubblicate e raccoglie tutte le altre in datiPubblici:
function rimuoviDatiTecnici({
supplierData,
dimensions,
...datiPubblici
}) {
return datiPubblici;
} In questo caso supplierData e dimensions non vengono restituiti, mentre id, title, price, currency e tags vengono copiati nel nuovo oggetto. È una tecnica pratica per filtrare metadati interni senza elencare manualmente tutte le proprietà da conservare.
Usare spread per comporre oggetti
Nel ritorno di normalizzaProdotto lo spread combina più oggetti:
return {
...datiSenzaMetadati,
...datiArricchiti,
tags: [...datiArricchiti.tags, "catalogo"]
}; Le proprietà successive hanno precedenza su quelle precedenti. Di conseguenza, se due oggetti contengono la stessa chiave, il valore di datiArricchiti sostituisce quello precedente. Infine, l’array tags viene copiato e arricchito con il tag "catalogo".
È importante ricordare che lo spread realizza una copia superficiale. Gli oggetti annidati vengono ancora condivisi, mentre array e oggetti al primo livello vengono copiati.
La pipeline con map
La chiamata:
const catalogo = prodottiRicevuti.map(normalizzaProdotto); applica la stessa trasformazione a ogni prodotto e restituisce un nuovo array. Il risultato contiene dati più semplici, nomi coerenti, prezzi formattati e una proprietà booleana che indica la disponibilità commerciale.
Best practice
- Destruttura solo ciò che usi: estrarre decine di proprietà rende la firma difficile da comprendere.
- Usa alias descrittivi: rinominare
titleinnomepuò migliorare la leggibilità quando il dominio dell’applicazione è in italiano. - Definisci valori predefiniti: array come
tagsdovrebbero avere un fallback per evitare errori durante iterazioni e concatenazioni. - Ricorda l’ordine dello spread: le proprietà più a destra sovrascrivono quelle precedenti.
- Non confondere rest e spread: la sintassi è simile, ma rest raccoglie valori, mentre spread li espande.
- Evita mutazioni: crea nuovi oggetti e nuovi array quando aggiungi o modifichi dati.
- Separa le responsabilità: una funzione dovrebbe filtrare, arricchire o formattare i dati, non fare tutto contemporaneamente.
Riepilogo
Destructuring, spread e rest sono strumenti fondamentali per costruire trasformazioni di dati concise e leggibili. Il destructuring estrae proprietà e valori, anche con alias e valori predefiniti. Il rest permette di raccogliere le proprietà rimanenti, mentre lo spread consente di creare nuovi oggetti e array combinando dati esistenti.
Nell’esempio abbiamo trasformato un catalogo esterno in una struttura adatta all’interfaccia dell’applicazione, eliminando metadati tecnici e aggiungendo informazioni calcolate. Questo approccio riduce il codice ripetitivo e rende ogni passaggio della pipeline più facile da testare.
Approfondisci con risorse ufficiali
- MDN - Destructuring assignment: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring
- MDN - Spread syntax: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
- MDN - Rest parameters: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters
- ECMAScript Language Specification: https://tc39.es/ecma262/
