La sintassi Spread permette di dividere un oggetto iterabile (come un'array o una stringa) nei suoi singoli elementi in situazioni dove sono richiesti zero o più argomenti (chiamate di funzione) o elementi (definizione con notazione letterale di un array); oppure di dividere le coppie di un oggetto dove sono richiesti zero o più coppie chiave-valore.
 

Sintassi

Per le chiamate alle funzioni:

myFunction(...iterableObj);

Per la definizione di array o stringhe con notazione letterale:

[...iterableObj, '4', 'five', 6];

Per la definizione di oggetti con notazione letterale (nuovi in ECMAScript 2018):

let objClone = { ...obj };

Esempi

Spread nelle chiamate delle funzioni

Rimpiazzare apply

È comune usare Function.prototype.apply nei casi in cui si desideri utilizzare gli elementi di un array come argomenti di una funzione.

function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction.apply(null, args);

Con la spread syntax quanto sopra può essere scritto come:

function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction(...args);

Qualsiasi argomento nell'elenco di argomenti può utilizzare la sintassi spread e può essere utilizzato più volte.

function myFunction(v, w, x, y, z) { }
var args = [0, 1];
myFunction(-1, ...args, 2, ...[3]);

Apply per new

Quando si chiama un constructor con new, non è possibile utilizzare direttamente un array e apply (apply fa una [[Call]] e non un [[Construct]]). Tuttavia, un array può essere facilmente utilizzato con "new" grazie alla sintassi spread:

var dateFields = [1970, 0, 1];  // 1 Jan 1970
var d = new Date(...dateFields);

Per usare new con un array di parametri senza la spread syntax, dovresti farlo indirettamente tramite l'applicazione parziale:

function applyAndNew(constructor, args) {
   function partial () {
      return constructor.apply(this, args);
   };
   if (typeof constructor.prototype === "object") {
      partial.prototype = Object.create(constructor.prototype);
   }
   return partial;
}


function myConstructor () {
   console.log("arguments.length: " + arguments.length);
   console.log(arguments);
   this.prop1="val1";
   this.prop2="val2";
};

var myArguments = ["hi", "how", "are", "you", "mr", null];
var myConstructorWithArguments = applyAndNew(myConstructor, myArguments);

console.log(new myConstructorWithArguments);
// (log interno di myConstructor):            arguments.length: 6
// (log interno di myConstructor):            ["hi", "how", "are", "you", "mr", null]
// (log di "new myConstructorWithArguments"): {prop1: "val1", prop2: "val2"}

Spread nella definizione di array con notazione letterale

Una migliore notazione letterale per la definizione di array

Senza la spread syntax, per creare un nuovo array usando un array esistente come parte di esso, la notazione letterale non è più sufficiente e deve essere sostituita con codice contenente una combinazione di push, splice, concat, etc. Con la spread syntax tutto diventa molto più succinto: 

var parts = ['shoulders', 'knees']; 
var lyrics = ['head', ...parts, 'and', 'toes']; 
// ["head", "shoulders", "knees", "and", "toes"]

Come per gli elenchi di argomenti, ... può essere utilizzato ovunque nel letterale dell'array e può essere utilizzato più volte.

Copiare un array

var arr = [1, 2, 3];
var arr2 = [...arr]; // come arr.slice()
arr2.push(4); 

// arr2 diventa [1, 2, 3, 4]
// arr rimane non influenzato

Note: Nota: la sintassi di diffusione fa effettivamente un livello in profondità durante la copia di un array. Pertanto, potrebbe non essere adatto alla copia di matrici multidimensionali come mostra il seguente esempio (è lo stesso con Object.assign() e la spread syntax).

var a = [[1], [2], [3]];
var b = [...a];
b.shift().shift(); // 1
// Anche l'array a viene modificato: [[], [2], [3]]

Un modo migliore per concatenare gli array

Array.concat è spesso usato per concatenare un array alla fine di un array esistente. Senza sintassi di diffusione questo è fatto così:

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// Appendiamo tutti gli elementi di arr2 in arr1
arr1 = arr1.concat(arr2);

Con la spread syntax diventa:

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1 = [...arr1, ...arr2];

Array.unshift è spesso usato per inserire un array di valori all'inizio di un array esistente. Senza la spread syntax questo è fatto così:

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// Inserisce tutti gli elementi dall'arr2 all'inizio dell'arr1
Array.prototype.unshift.apply(arr1, arr2) // arr1 adesso è [3, 4, 5, 0, 1, 2]

Con la spread syntax, questo diventa [Si noti, tuttavia, che questo crea un nuovo array denominato arr1. A differenza di Array.unshift, non modifica l'array originale arr1]:

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1 = [...arr2, ...arr1]; // arr1 adesso e' [3, 4, 5, 0, 1, 2]

Spread nella definizione di oggetti con notazione letterale

La proposta Rest/Spread per ECMAScript (stage 4) aggiunge le proprietà spread anche ai letterali degli oggetti. Copia le proprie proprietà enumerabili da un oggetto fornito su un nuovo oggetto.

Copie superficiali (escludendo il prototype) o fusioni di oggetti sono ora possibili usando una sintassi più breve rispetto a Object.assign().

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };

var clonedObj = { ...obj1 };
// Object { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 }

Nota che Object.assign() attiva i setters mentre la spread syntax no.

Si noti che non è possibile sostituire o imitare la funzione Object.assign()

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
const merge = ( ...objects ) => ( { ...objects } );

var mergedObj = merge ( obj1, obj2);
// Object { 0: { foo: 'bar', x: 42 }, 1: { foo: 'baz', y: 13 } }

var mergedObj = merge ( {}, obj1, obj2);
// Object { 0: {}, 1: { foo: 'bar', x: 42 }, 2: { foo: 'baz', y: 13 } }

Nell'esempio precedente, la spread syntax non funziona come previsto: estende un array di argomenti nel letterale dell'oggetto, a causa del parametro rest.

Solo per gli iterabili

La spread syntax (diverso da quello delle proprietà spread) può essere applicata solo su oggetti iterabili:

var obj = {'key1': 'value1'};
var array = [...obj]; // TypeError: obj is not iterable

Spread con tanti valori

Quando si utilizza la spread syntax per le chiamate di funzione, bisogna tenere presente la possibilità di superare il limite di lunghezza dell'argomento del motore JavaScript. Vedi apply() per maggiori dettagli.

Sintassi Rest (parametri)

La sintassi Rest sembra esattamente come la sintassi di diffusione, ma è usata per destrutturare array e oggetti. In un certo senso, la sintassi di rest è l'opposto della spread syntax: spread "espande" un array nei suoi elementi, mentre rest raccoglie più elementi e li "condensa" in un singolo elemento. Vedi i parametri rest.

Specifiche

Specifica Stato Commento
ECMAScript 2015 (6th Edition, ECMA-262) Standard Definito in diverse sezioni della specifica: Array Initializer, Argument Lists
ECMAScript 2018 (ECMA-262) Standard Definito in Object Initializer
ECMAScript Latest Draft (ECMA-262) Draft Nessun cambiamento.
ECMAScript Latest Draft (ECMA-262) Draft Nessun cambiamento.

Compatibilità con i browser

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidEdge MobileFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
Spread in array literalsChrome Full support 46Edge Full support 12Firefox Full support 16IE No support NoOpera Full support 37Safari Full support 8WebView Android Full support 46Chrome Android Full support 46Edge Mobile Full support 12Firefox Android Full support 16Opera Android Full support 37Safari iOS Full support 8Samsung Internet Android Full support 5.0nodejs Full support 5.0.0
Full support 5.0.0
Full support 4.0.0
Disabled
Disabled From version 4.0.0: this feature is behind the --harmony runtime flag.
Spread in function callsChrome Full support 46Edge Full support 12Firefox Full support 27IE No support NoOpera Full support 37Safari Full support 8WebView Android Full support 46Chrome Android Full support 46Edge Mobile Full support 12Firefox Android Full support 27Opera Android Full support 37Safari iOS Full support 8Samsung Internet Android Full support 5.0nodejs Full support 5.0.0
Full support 5.0.0
Full support 4.0.0
Disabled
Disabled From version 4.0.0: this feature is behind the --harmony runtime flag.
Spread in destructuringChrome Full support 49Edge No support NoFirefox Full support 34IE No support NoOpera Full support 37Safari ? WebView Android Full support 49Chrome Android Full support 49Edge Mobile No support NoFirefox Android Full support 34Opera Android Full support 37Safari iOS ? Samsung Internet Android Full support 5.0nodejs Full support Yes
Spread in object literals
Experimental
Chrome Full support 60Edge No support NoFirefox Full support 55IE No support NoOpera Full support 47Safari Full support 11.1WebView Android Full support 60Chrome Android Full support 60Edge Mobile No support NoFirefox Android Full support 55Opera Android ? Safari iOS Full support 11.1Samsung Internet Android Full support 8.2nodejs Full support 8.3.0
Full support 8.3.0
Full support 8.0.0
Disabled
Disabled From version 8.0.0: this feature is behind the --harmony runtime flag.

Legend

Full support  
Full support
No support  
No support
Compatibility unknown  
Compatibility unknown
Experimental. Expect behavior to change in the future.
Experimental. Expect behavior to change in the future.
User must explicitly enable this feature.
User must explicitly enable this feature.

Vedi anche

Tag del documento e collaboratori

Hanno collaborato alla realizzazione di questa pagina: spinjam, IsibisiDev, mdnwebdocs-bot, quackmore, adrisimo74
Ultima modifica di: spinjam,