Spread e Rest operator (...): stesso simbolo, lavori opposti

Copia, merge, parametri variadic — shallow copy oggetti, clone array

· 572 parole

Tre puntini, ..., ma due significati opposti a seconda di dove li scrivi. Lo spread espande un array o un oggetto nei suoi elementi; il rest fa l'esatto contrario: raccoglie più elementi in un unico contenitore.

Pensa alla differenza tra svuotare uno scatolone rovesciandone il contenuto sul tavolo (spread: da uno, tanti pezzi separati) e riempire uno scatolone raccogliendo tutto ciò che trovi in giro (rest: da tanti pezzi, uno scatolone). Stesso gesto — «scatolone» — ma verso opposti.

1. Spread: da un contenitore, i suoi elementi separati

Lo spread prende un iterabile (array, stringa, o le proprietà di un oggetto) e lo espande dove ci si aspettano più valori: un elenco di argomenti, gli elementi di un nuovo array.

function somma(x, y, z) {
    return x + y + z;
}

const numeri = [1, 2, 3];

somma(...numeri); // 6 -- come scrivere somma(1, 2, 3)

Math.max(...numeri); // 3 -- Math.max vuole valori separati, non un array

Fonte: MDN Web Docs — «Spread syntax»: espande un iterabile nei punti dove sono attesi zero o più argomenti o elementi.

2. Copia array e oggetti: shallow, non deep

const originale = [1, 2, 3];
const copia = [...originale];

const obj1 = {
    nome: "Ada",
    x: 42
};

const clone = {
    ...obj1
};

Il punto tecnico da ricordare: lo spread crea una copia superficiale (shallow copy), senza il prototipo dell'oggetto originale, senza le proprietà non enumerabili. Se una proprietà contiene a sua volta un oggetto, quell'oggetto interno non viene duplicato: la copia e l'originale continuano a puntare allo stesso oggetto annidato.

const utente = {
    nome: "Ada",
    indirizzo: {
        citta: "Roma"
    }
};

const copiaUtente = {
    ...utente
};

copiaUtente.indirizzo.citta = "Milano";
console.log(utente.indirizzo.citta); // "Milano" -- cambiato anche l'originale!

Fonte: MDN Web Docs — «Spread syntax»: un singolo spread crea una copia superficiale dell'oggetto originale (senza proprietà non enumerabili e senza copiare il prototipo).

3. Merge: unire più oggetti, l'ordine decide chi vince

const base = {
    tema: "chiaro",
    lingua: "it"
};

const override = {
    tema: "scuro"
};

const impostazioni = {
    ...base,
    ...override
};

// { tema: "scuro", lingua: "it" }
// override vince perché è scritto dopo

Quando due oggetti condividono la stessa proprietà, vince quella scritta per ultima nell'espressione. È lo stesso principio, applicato agli oggetti, dell'ultima dichiarazione che vince in un cascade CSS.

Una differenza sottile rispetto a Object.assign(), segnalata da MDN: lo spread non attiva gli eventuali setter definiti sull'oggetto di destinazione, mentre Object.assign() sì.

Fonte ufficiale: MDN Web Docs — «Spread syntax»: nel merge di oggetti, le proprietà successive sovrascrivono le precedenti; a differenza di Object.assign(), lo spread non attiva i setter.

4. Rest: parametri «variadic», da tanti argomenti a un array

Nella lista dei parametri di una funzione, gli stessi tre puntini fanno il lavoro opposto: raccolgono un numero qualsiasi di argomenti in un vero array.

function sommaTutti(...numeri) {
    return numeri.reduce((tot, n) => tot + n, 0);
}

sommaTutti(1, 2, 3, 4);
// 10 -- accetta quanti argomenti vuoi

Il rest parameter, per sintassi obbligatoria, deve essere l'ultimo della lista dei parametri, se ne scriviamo un altro dopo è un errore.

// Errore: il rest deve essere l'ultimo parametro
// function f(a, ...resto, b) { }

// Corretto
function f(a, ...resto) {
}

In sintesi

  Cosa fa Esempio
Spread in chiamata Espande un array come argomenti separati somma(...numeri)
Spread in array Copia o unisce array [...arr1, ...arr2]
Spread in oggetto Copia o unisce oggetti (shallow) { ...obj1, ...obj2 }
Rest in parametri Raccoglie argomenti in un array function f(...args) {}

Stesso simbolo, stessa parola nel nome, ma dove lo scrivi decide se stai aprendo un contenitore o chiudendone uno. Ricordarsi che la copia è sempre superficiale evita uno dei bug più comuni e silenziosi in JavaScript: modificare per sbaglio l'originale credendo di lavorare solo sulla copia.

Accedi o registrati per votare, salvare o commentare la pillola

Commenti (0)

Registrati per commentare, fare domande e proporre l'argomento della prossima pillola (oppure accedi se hai già un account).

Nessun commento. Sii il primo a scrivere qualcosa.

Pillole correlate