Menu

Destructuring in JavaScript: oggetti, array, default e rest

Come funziona il destructuring in JavaScript: estrarre valori da oggetti e array, rinominare variabili, valori predefiniti, pattern annidati e parametri di funzione.

Questa pagina include editor eseguibili: modifica, esegui e vedi subito l'output.

Il destructuring è pattern matching sulle forme

Il destructuring ti permette di scrivere un pattern che rispecchia la forma di un oggetto o di un array ed estrarre i valori per nome o per posizione in una sola riga. Invece di prendere il valore una proprietà alla volta, descrivi quello che vuoi e JavaScript te lo consegna.

Le due varianti:

Le parentesi graffe corrispondono a un oggetto tramite i nomi delle proprietà. Le parentesi quadre corrispondono a un array tramite la posizione. In entrambi i casi, le variabili a sinistra sono nuove dichiarazioni: non stai accedendo al valore per indice, stai descrivendo un pattern che ne estrae i pezzi.

Prima che esistesse il destructuring, lo stesso codice era così:

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

Non è la fine del mondo, ma diventa ripetitivo quando lo fai in ogni funzione.

Il destructuring degli oggetti usa i nomi delle proprietà

Per gli oggetti, i nomi dentro le graffe devono corrispondere ai nomi delle proprietà dell'oggetto di origine. L'ordine non conta: JavaScript le cerca per chiave.

Se una proprietà non esiste nell'oggetto, la variabile vale undefined, senza errori:

È importante ricordare questo comportamento silenzioso con undefined quando un errore di battitura nel nome di una proprietà ti fa grattare la testa alle due di notte.

Rinominare le variabili

A volte il nome della proprietà dell'oggetto non è quello che vuoi dare alla variabile: magari va in conflitto con qualcos'altro nello scope, o l'API usa una convenzione di nomi che non ti piace. Usa original: newName per assegnare un altro nome:

Leggilo come "prendi la proprietà id e chiamala userId". Prima viene il nome della proprietà, dopo i due punti il nome della nuova variabile. Sembra un'annotazione di tipo di altri linguaggi, ma non lo è.

Valori predefiniti

Se una proprietà potrebbe mancare, assegnale un valore predefinito direttamente nel pattern:

I valori predefiniti entrano in gioco solo quando il valore è undefined. null, 0 e "" passano tutti senza modifiche:

Questo sorprende molti. Se vuoi che anche null attivi il valore predefinito, ti serve un controllo esplicito, oppure puoi usare l'operatore di nullish coalescing ?? dopo il destructuring.

Puoi combinare valori predefiniti e rinomina:

Il destructuring degli array usa la posizione

Gli array non hanno nomi, solo indici, quindi il pattern corrisponde per posizione. Usa le virgole per saltare gli elementi che non ti interessano:

Le due virgole iniziali dicono "salta gli indici 0 e 1". Visivamente è un po' denso, ma è comodo quando vuoi un solo valore dal mezzo.

Il destructuring degli array dà il meglio con le funzioni che restituiscono tuple:

Lo stesso pattern compare ovunque negli hook di React: const [count, setCount] = useState(0).

Pattern rest: raccogliere gli avanzi

Dentro un pattern di destructuring, ...name raccoglie in una nuova variabile tutto ciò che non è stato preso per nome o per posizione.

Negli array, il rest prende la coda:

Negli oggetti, il rest prende tutte le proprietà che non sono state nominate esplicitamente:

È il modo idiomatico per togliere un campo da un oggetto senza modificarlo: rest è un nuovo oggetto che contiene tutto tranne id.

Il rest deve essere l'ultimo elemento del pattern. const [...init, last] è un errore di sintassi.

Destructuring annidato

I pattern si possono annidare. Se una proprietà è a sua volta un oggetto o un array, puoi destrutturarla nella stessa espressione:

È potente, ma usalo con giudizio. Tre livelli di graffe annidate cominciano a sembrare un rompicapo. Quando succede, estrai i valori intermedi in variabili a sé: la leggibilità batte l'astuzia.

Un tranello: data: { user } nel pattern non crea una variabile chiamata data. È un'indicazione che dice "scendi dentro data e continua a destrutturare". Se ti serve anche data, aggiungila a parte:

Destructuring dei parametri di funzione

Il posto in cui userai più spesso il destructuring è l'elenco dei parametri di una funzione. Trasforma il "passa un oggetto di opzioni" in una firma che si documenta da sola:

Dal lato della chiamata sembra una normale chiamata con un oggetto di opzioni. Dentro la funzione ottieni variabili con nome e valori predefiniti, senza più codice ripetitivo come options.name || "default".

Un punto delicato: chiamare questa funzione senza argomenti la fa andare in crash, perché non puoi destrutturare undefined. Dai un valore predefinito all'intero parametro:

Il = {} dopo il pattern dice "se non arriva nessun argomento, fai finta che sia un oggetto vuoto". Poi entrano in gioco i valori predefiniti interni.

Scambiare e riassegnare

Il destructuring funziona anche con variabili già dichiarate, ma serve racchiudere tra parentesi il pattern dell'oggetto (altrimenti JavaScript legge la { come l'inizio di un blocco):

Lo scambio con gli array è pulito. La riassegnazione con gli oggetti è più rara, ma vale la pena ricordarsi il trucco delle parentesi per quando ti servirà.

Un esempio realistico

Mettiamo insieme quasi tutto quello che abbiamo visto: una funzione che elabora la risposta di un'API:

Ogni livello destrutturato ha un valore predefinito, quindi la funzione sopravvive a dati parziali senza una pila di controlli if. È questo il vero vantaggio: firme precise e tolleranti allo stesso tempo.

Prossimo passo: lo spread sugli oggetti

Il destructuring tira fuori i valori dagli oggetti. Lo spread li mette dentro: copiare, unire e sovrascrivere. I due vanno sempre a braccetto nel JavaScript moderno, e lo spread è il prossimo argomento.

Domande frequenti

Cos'è il destructuring in JavaScript?

Il destructuring (assegnazione destrutturante) è una sintassi per estrarre valori da oggetti o array e assegnarli a variabili in un solo passaggio. const { name } = user; prende la proprietà name da user. const [first, second] = list; prende i primi due elementi di list. È un pattern a sinistra di = che rispecchia la forma del valore a destra.

Come si rinomina una variabile con il destructuring?

Usa la sintassi { original: newName }. const { name: username } = user; estrae la proprietà name da user e la assegna a una variabile locale chiamata username. È facile scambiarla per un'annotazione di tipo: ricorda che prima viene il nome della proprietà, poi, dopo i due punti, il nome della nuova variabile.

Si possono impostare valori predefiniti con il destructuring?

Sì. const { timeout = 5000 } = options; usa 5000 se options.timeout è undefined. I valori predefiniti si applicano solo a undefined: null, 0 e '' passano senza modifiche. Puoi combinare valori predefiniti e rinomina: const { t: timeout = 5000 } = options;.

Che differenza c'è tra destructuring e spread?

Si somigliano ma fanno cose opposte. Il destructuring (const { a, b } = obj) tira fuori i valori da una struttura. Lo spread (const copy = { ...obj }) mette i valori dentro una nuova struttura. I ... dentro un pattern di destructuring sono un pattern rest: raccolgono gli avanzi in una nuova variabile.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA