The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
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 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 di diffusione 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 "nuovo" grazie alla spread syntax:
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
| Desktop | Mobile | Server | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Spread in array literals | Chrome Full support 46 | Edge Full support 12 | Firefox Full support 16 | IE No support No | Opera Full support 37 | Safari Full support 8 | WebView Android Full support 46 | Chrome Android Full support 46 | Edge Mobile Full support 12 | Firefox Android Full support 16 | Opera Android Full support 37 | Safari iOS Full support 8 | Samsung Internet Android Full support 5.0 | nodejs
Full support
5.0.0
|
| Spread in function calls | Chrome Full support 46 | Edge Full support 12 | Firefox Full support 27 | IE No support No | Opera Full support 37 | Safari Full support 8 | WebView Android Full support 46 | Chrome Android Full support 46 | Edge Mobile Full support 12 | Firefox Android Full support 27 | Opera Android Full support 37 | Safari iOS Full support 8 | Samsung Internet Android Full support 5.0 | nodejs
Full support
5.0.0
|
| Spread in destructuring | Chrome Full support 49 | Edge No support No | Firefox Full support 34 | IE No support No | Opera Full support 37 | Safari ? | WebView Android Full support 49 | Chrome Android Full support 49 | Edge Mobile No support No | Firefox Android Full support 34 | Opera Android Full support 37 | Safari iOS ? | Samsung Internet Android Full support 5.0 | nodejs Full support Yes |
| Spread in object literals | Chrome Full support 60 | Edge No support No | Firefox Full support 55 | IE No support No | Opera Full support 47 | Safari Full support 11.1 | WebView Android Full support 60 | Chrome Android Full support 60 | Edge Mobile No support No | Firefox Android Full support 55 | Opera Android ? | Safari iOS Full support 11.1 | Samsung Internet Android Full support 8.2 | nodejs
Full support
8.3.0
|
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
- Rest parameters (also ‘
...’) - fn.apply (also ‘
...’)