Questa traduzione è incompleta. Collabora alla traduzione di questo articolo dall’originale in lingua inglese.

La sintassi Spread permette a un'espression iterabile come un'array di essere espansa [expanded in places(?)] dove ci si aspetta zero o più argomenti (per le chiamate delle funzioni) o elementi (per gli array letterali); oppure a un'espressione oggetto di essere espansa [expanded in places(?)] dove ci si aspetta zero o più coppie chiave-valore.

Sintassi

Per le chiamate alle funzioni:

myFunction(...iterableObj);

Per gli array letterali o le stringhe:

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

Per gli oggetti letterali (nuovi in ECMAScript 2018):

let objClone = { ...obj };

Esempi

Spread nelle chiamate alle funzioni

Rimpiazzare apply

E' prassi comune usare Function.prototype.apply quando si vuole usare 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 sintassi spread questo può essere scritto così:

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

Qualsiasi argomento nella lista degli argomenti può usare la sintassi spread e può essere usato 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 costruttore con  new, non è possibile usare direttamente un array con apply (apply fa una [[Call]] e non un [[Construct]]). Tuttavia un array può essere facilmente usato 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 sintassi spread avreste dovuto farlo indirettamente attraveso un'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 negli array letterali

Un array letterale più potente

Senza la sintassi spread per creare un nuovo array, usando un array preesistente come parte di esso, la sintassi letterale non è più sufficiente e un codice imperativo deve essere usato invece di una combinazione di push, splice, concat, etc. Con la sintassi spread diventa molto più succinto: 

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

Porprio come spread in una lista di argomenti, ... può essere usato ovunque negli array letterali, e può essere usato 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: La sintassi spread effettivamente va a un livello più in profondità mentre copia un array. Quindi può essere utile quando si copiano array multidimensionali come mostra l'esempio qui sotto (è lo stesso tra Object.assign() e la sintassi Spread).

var a = [[1], [2], [3]];
var b = [...a];
b.shift().shift(); // 1
// Anche il nuovo array a è affetto: [[], [2], [3]]

Una maniera migliore per concatenare gli array

Array.concat è spesso usato per concatenare un array alla fine di un array preesistente. Senza la sintassi spread si farebbe 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 sintassi spread 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 preesistente. Senza la sintassi spread si farebbe così:

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

Con la sintassi spread questo diventa [Si noti, tuttavia, che questo crea un nuovo array arr1. Diversamente da Array.unshift, non modifica l'array originale arr1 (in-place)]:

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

Spread negli oggetti letterali

Le Proprietà Rest/Spread per i propositi di ECMAScript (stage 4) aggiungono le proprietà spread anche agli oggetti letterali. Copiano le proprietà enumerabili proprie (own) di un oggetto dato, in 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 };
// Oggetto { foo: "bar", x: 42 }

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

Si noti che Object.assign() scatena i setters mentre la sintassi spread no.

Solo per gli iterabili

La sintassi spread (a parte nel caso delle proprietà spread) può essere applicata solo su oggetti iterabili:

var obj = {'key1': 'value1'};
var array = [...obj]; // TypeError: obj non è iterabile

Spread con tanti valori

Quando si usa la sintassi spread nelle chiamate di funzioni, bisogna essere consapevoli della possibilità di eccedere il limite della lunghezza degli argomenti previsto dal motore JavaScript. Si veda apply() per maggiori dettagli.

Sintassi Rest (parametri)

La sintassi Rest appare esattamente come la sintassi spread, ma è usata per destrutturare gli array e gli oggetti. In un certo senso, la sintassi rest è l'opposto della sintassi spread: spread 'espande' un array nei suoi elementi, mentre rest colleziona molteplici elementi e li 'condensa' in un singolo elemento. Si veda parametri rest.

Specifiche

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262) Standard Definito in diverse sezioni delle specifiche: Array Initializer, Argument Lists
ECMAScript Latest Draft (ECMA-262) Draft Nessun cambiamento.
ECMAScript Latest Draft (ECMA-262) Draft Definito in Object Initializer

Compatibilità nei browser

FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
Spread in array literals461216 No378
Spread in function calls461227 No378
Spread in destructuring49 No34 No37 ?
Spread in object literals60 No55 No ? No
FeatureAndroid webviewChrome for AndroidEdge mobileFirefox for AndroidOpera AndroidiOS SafariSamsung Internet
Spread in array literals464612163785.0
Spread in function calls464612273785.0
Spread in destructuring4949 No3437 ?5.0
Spread in object literals6060 No55 ? No No

Si veda anche

Tag del documento e collaboratori

 Hanno collaborato alla realizzazione di questa pagina: adrisimo74
 Ultima modifica di: adrisimo74,