Sintassi Rest e Spread in JavaScript
Scopri i parametri rest e la sintassi spread in JavaScript ES6: come raccogliere argomenti in un array e come espandere iterabili in valori separati.
In JavaScript, il token a tre punti ... svolge due compiti opposti a seconda di dove viene scritto. Come parametro di funzione raccoglie molti argomenti in un singolo array — questo è un parametro rest. In tutti gli altri contesti espande un iterabile o un object nei suoi singoli elementi — questa è la sintassi spread. Stesso simbolo, significato speculare.
Entrambi sono stati introdotti in ES6 (2015). Questa pagina tratta i parametri rest (inclusa la regola che devono venire per ultimi), lo spread nelle chiamate di funzione, nei letterali di array e nei letterali di object, come copiare e unire con spread, le differenze tra rest e spread, e perché entrambi superano il vecchio object arguments.
Comprendere i Parametri Rest in JavaScript
Un parametro rest consente a una funzione di accettare un numero indefinito di argomenti e riceverli come un vero array. Si scrive ... seguito da un nome; quel nome diventa un array contenente ogni argomento che non è stato abbinato a un parametro precedente.
Sintassi e Utilizzo
Nell'esempio seguente, numbers è un array ordinario, quindi puoi chiamare metodi di array come reduce direttamente su di esso — senza alcuna conversione necessaria.
Il Parametro Rest Deve Essere l'Ultimo
Una funzione può avere solo uno parametro rest, e deve essere l'ultimo nella lista dei parametri. I parametri con nome che lo precedono vengono riempiti per primi; il parametro rest raccoglie quindi tutto ciò che rimane. Posizionarlo altrove provoca un SyntaxError.
Vantaggi Rispetto all'Object arguments
Prima di ES6, l'unico modo per leggere tutti gli argomenti era il speciale object arguments disponibile all'interno delle funzioni non-arrow. I parametri rest sono migliori in quasi ogni aspetto:
- Un vero array.
argumentsè simile a un array (ha unalengthe degli indici) ma manca dimap,filter,reduce, ecc. Un parametro rest è un array genuino. - Esplicito e leggibile. La firma
function sum(...numbers)indica al lettore che la funzione accetta un elenco variabile.argumentsè invisibile nella firma. - Puoi nominare solo gli extra. Combina parametri fissi con un parametro rest, come mostrato sopra —
argumentscontiene sempre ogni argomento, inclusi quelli già nominati. - Funziona con le arrow function. Le arrow function non hanno il proprio object
arguments, quindi un parametro rest è l'unico modo per raccogliere argomenti variabili in una arrow function.
Approfondimento sulla Sintassi Spread
La sintassi spread espande un iterabile — un array, una string, un Set, una Map, o qualsiasi iterabile — nei suoi singoli elementi ovunque ci si aspetti un elenco di valori. I tre contesti in cui la utilizzerai sono chiamate di funzione, letterali di array e letterali di object.
Spread nei Letterali di Array
All'interno di [ ], spread inserisce ogni elemento di un iterabile nel nuovo array. Questo è il modo più pulito per inserire un array in un altro in qualsiasi posizione:
Poiché le string sono iterabili, espanderne una produce un array dei suoi caratteri:
Spread nelle Chiamate di Funzione
In una chiamata di funzione, spread trasforma un array in un elenco di argomenti separati. Questo sostituisce il vecchio pattern func.apply(null, array):
Spread nei Letterali di Object
All'interno di { }, spread copia le proprietà enumerabili proprie di un object in un nuovo object. Quando le chiavi collidono, vince il valore successivo — il che rende spread perfetto per applicare sostituzioni o valori predefiniti:
Copiare e Unire
Spread è il modo idiomatico per creare una copia superficiale o unire collezioni senza mutare gli originali:
Spread è superficiale. Copia solo i valori di primo livello. Gli object e gli array annidati sono ancora condivisi per riferimento, quindi mutare un valore annidato influisce su entrambe le copie:
Rest vs Spread: Come Distinguerli
Il token ... appare identico in entrambi i ruoli, quindi usa la posizione per capire quale stai leggendo:
| Parametro rest | Sintassi spread | |
|---|---|---|
| Dove appare | Nella lista dei parametri di una funzione | In una chiamata, un letterale di array o un letterale di object |
| Cosa fa | Raccoglie molti valori in un array | Espande un iterabile/object in molti valori |
Lato del = | Lato sinistro (una destinazione di destrutturazione) | Lato destro (un valore che viene prodotto) |
| Esempio | function f(...args) {} | f(...args) |
Un test semplice: se ...x sta ricevendo valori, è rest; se sta producendo valori, è spread.
Combinare Parametri Rest e Sintassi Spread
I due sono immagini speculari, quindi si abbinano naturalmente — rest raccoglie gli argomenti in un array in entrata, e spread espande un array in argomenti in uscita:
Un pattern comune nel mondo reale è un wrapper che inoltra ogni argomento a un'altra funzione:
Destrutturazione con il Pattern Rest
In un'assegnazione di destrutturazione, il pattern rest cattura le proprietà o gli elementi che non hai nominato esplicitamente. Negli object produce un object con le chiavi rimanenti; negli array, un array degli elementi restanti.
Conclusione
Il token ... è una delle aggiunte più utili che ES6 ha apportato a JavaScript. Come parametro rest raccoglie un numero variabile di argomenti in un array pulito (e sostituisce il scomodo object arguments); come sintassi spread espande iterabili nelle chiamate di funzione, nei letterali di array e nei letterali di object, fornendoti copie superficiali e fusioni concise. Ricorda le due regole che ingannano di più: un parametro rest deve essere l'ultimo parametro, e le copie con spread sono superficiali.
Argomenti Correlati
- Assegnazione di destrutturazione — estrai valori da array e object, spesso abbinata al pattern rest.
- JavaScript Array — la struttura dati che i parametri rest ti consegnano e che spread espande.
- Arrow function rivisitate — perché le arrow function si affidano ai parametri rest invece di
arguments. - Function binding — controllo di
this, spesso combinato con spread quando si inoltrano argomenti.