Die Spread-Syntax erlaubt es, einen einzelnen Array-Ausdruck oder String an Stellen zu expandieren, an denen Null oder mehr Argumente (für Funktionsaufrufe) oder Elemente (für Array-Literale) erwartet werden, oder einen Objekt-Ausdruck an Stellen zu expandieren, an denen Null oder mehr Schlüssel-Wert-Paare (für Objektliterale) erwartet werden.

Syntax

Für Funktionsaufrufe:

myFunction(...iterableObj);

Für Array-Literale oder Strings:

[...iterableObj, '4', 'fünf', 6];

Für Objektliterale (neu in ECMAScript 2018):

let objClone = { ...obj };

Beispiele

Spread in Funktionsaufrufen

Apply ersetzen

Es ist üblich Function.prototype.apply zu benutzen, wenn man die Elemente eines Arrays als Argumente eines Funktionsaufrufs nutzen möchte.

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

Mit der Spread-Syntax lässt sich das ganze wie folgt schreiben:

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

Jedes Argument der Argumentliste kann die Spread-Syntax verwenden, und sie kann auch mehrfach verwendet werden.

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

Apply bei new

Beim Aufruf eines Konstruktors mit new, ist es nicht möglich ein Array und apply direkt zu benutzen (apply führt [[Call]] und nicht [[Construct]] aus). Allerdings kann dank der Spread-Syntax ein Array mit new verwendet werden:

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

Um new mit einem Array ohne die Spread-Syntax zu nutzen, müsste man das indirekt mit Partial Application umsetzen:

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", "wie", "geht's", "dir", "kumpel", null];
var myConstructorWithArguments = applyAndNew(myConstructor, myArguments);

console.log(new myConstructorWithArguments);
// (internal log of myConstructor):           arguments.length: 6
// (internal log of myConstructor):           ["hi", "wie", "geht's", "dir", "kumpel", null]
// (log of "new myConstructorWithArguments"): {prop1: "val1", prop2: "val2"}

Spread bei Array-Literalen

Ein mächtigeres Array-Literal

Ohne Spread-Syntax ist die Array-Literal-Syntax nicht ausreichend, um ein neues Array zu erzeugen, das aus einem bereits existierenden Array besteht. Man muss dann auf imperative Programmierung mit einer Kombination aus push, splice, concat, etc. umsteigen. Mit Spread-Syntax wird der Code kurz und bündig:

var parts = ['Schultern', 'Knie']; 
var lyrics = ['Kopf', ...parts, 'und', 'Zehen']; 
// ["Kopf", "Schultern", "Knie", "und", "Zehen"]

Genau wie bei Argumentlisten von Funktionsaufrufen kann ... überall und mehrach bei Array-Literalen benutzt werden.

Ein Array kopieren

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

// arr2 enthält[1, 2, 3, 4]
// arr bleibt unverändert

Bemerkung: Spread-Syntax geht beim Kopieren eines Arrays effektiv eine Ebene tief. Daher kann es für das Kopieren mehrdimensionaler Arrays ungeeignet sein, wie das folgende Beispiel zeigt (dasselbe gilt für Object.assign() und Spread-Syntax).

var a = [[1], [2], [3]];
var b = [...a];
b.shift().shift(); // 1
// Auch Array a wurde verändert. [[], [2], [3]]

Eine bessere Möglichkeit, Arrays zu verketten

Array.concat wird oft verwendet, um ein Array an das Ende eines bestehenden Arrays anzuhängen. Ohne Spread-Syntax wird dies wie folgt gemacht:

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// Hänge alle Elemente von arr2 an arr1
arr1 = arr1.concat(arr2);

Mit Spread-Syntax wird daraus:

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

Array.unshift wird oft verwendet, um ein Array von Werten am Anfang eines bestehenden Arrays einzufügen. Ohne Spread-Syntax wird dies wie folgt gemacht:

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// Alle Items von arr2 auf arr1 voranstellen
Array.prototype.unshift.apply(arr1, arr2) // arr1 ist jetzt [3, 4, 5, 0, 1, 2]

Bei der Spread-Syntax wird dies zu [Beachten Sie jedoch, dass dies ein neues Array arr1 erzeugt. Im Gegensatz zu Array.unshift ändert es nicht das ursprüngliche Array arr1 in-place]:

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

Spread für Objektliterale

Der Vorschlag zu Rest-/Spread-Attributen für ECMAScript (Stufe 4) fügt Spread-Attribute zu Objektliteralen hinzu. Dadurch werden die abzählbaren Attribute von einem gegebenen Objekt zu einem neuen hinzugefügt.

Flaches Klonen (ohne prototype) oder Zusammenführen von Objekten ist nun mit einer kürzeren Syntax als Object.assign() möglich.

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 }

Beachten Sie, dass Object.assign()} im Gegensatz zur Spread-Syntax Setter auslöst.

Beachten Sie, dass Sie die Funktion Object.assign() weder ersetzen noch nachahmen können:

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 } }

Im obigen Beispiel funktioniert der Spread-Operator nicht wie erwartet: er klappt ein Array von Argumenten aus und liefert ein Array dieser, aufgrund des rest Parameters.

Nur für iterierbare Objekte

Spread-Syntax (anders als bei Spread-Eigenschaften) kann nur auf iterierbare Objekte angewendet werden:

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

Spread mit mehreren Werten

When using spread syntax for function calls, be aware of the possibility of exceeding the JavaScript engine's argument length limit. Seefor more details.

Beachten Sie bei der Verwendung von Spread-Syntax für Funktionsaufrufe die Möglichkeit der Überschreitung der Argumentlängenbegrenzung der JavaScript-Engine. Siehe apply() für weitere Details.

Rest-Syntax (Parameter)

Rest-Syntax sieht genauso aus wie die Spread-Syntax und wird für das Destrukturieren von Arrays und Objekten eingesetzt. Rest-Syntax ist sozusagen das Gegenteil von Spread-Syntax: Spread klappt die einzelnen Bestandteile eines Arrays aus, während Rest verschiedene einzelne Elemente zu einem Array zusammenfasst. Siehe Rest-Parameter.

Spezifikationen

Spezifikation Status Kommentar
ECMAScript 2015 (6th Edition, ECMA-262) Standard Definiert in mehreren Abschnitten der Spezifikation: Array Initializer, Argument Lists
ECMAScript Latest Draft (ECMA-262) Entwurf Keine Änderungen
ECMAScript Latest Draft (ECMA-262) Entwurf Definiert in Object Initializer

Browser-Kompatibilität

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid WebviewChrome für AndroidEdge MobileFirefox für AndroidOpera für AndroidiOS SafariSamsung InternetNode.js
Spread in array literalsChrome Vollständige Unterstützung 46Edge Vollständige Unterstützung 12Firefox Vollständige Unterstützung 16IE Keine Unterstützung NeinOpera Vollständige Unterstützung 37Safari Vollständige Unterstützung 8WebView Android Vollständige Unterstützung 46Chrome Android Vollständige Unterstützung 46Edge Mobile Vollständige Unterstützung 12Firefox Android Vollständige Unterstützung 16Opera Android Vollständige Unterstützung 37Safari iOS Vollständige Unterstützung 8Samsung Internet Android Vollständige Unterstützung 5.0nodejs Vollständige Unterstützung 5.0.0
Vollständige Unterstützung 5.0.0
Vollständige Unterstützung 4.0.0
Deaktiviert
Deaktiviert From version 4.0.0: this feature is behind the --harmony runtime flag.
Spread in function callsChrome Vollständige Unterstützung 46Edge Vollständige Unterstützung 12Firefox Vollständige Unterstützung 27IE Keine Unterstützung NeinOpera Vollständige Unterstützung 37Safari Vollständige Unterstützung 8WebView Android Vollständige Unterstützung 46Chrome Android Vollständige Unterstützung 46Edge Mobile Vollständige Unterstützung 12Firefox Android Vollständige Unterstützung 27Opera Android Vollständige Unterstützung 37Safari iOS Vollständige Unterstützung 8Samsung Internet Android Vollständige Unterstützung 5.0nodejs Vollständige Unterstützung 5.0.0
Vollständige Unterstützung 5.0.0
Vollständige Unterstützung 4.0.0
Deaktiviert
Deaktiviert From version 4.0.0: this feature is behind the --harmony runtime flag.
Spread in destructuringChrome Vollständige Unterstützung 49Edge Keine Unterstützung NeinFirefox Vollständige Unterstützung 34IE Keine Unterstützung NeinOpera Vollständige Unterstützung 37Safari ? WebView Android Vollständige Unterstützung 49Chrome Android Vollständige Unterstützung 49Edge Mobile Keine Unterstützung NeinFirefox Android Vollständige Unterstützung 34Opera Android Vollständige Unterstützung 37Safari iOS ? Samsung Internet Android Vollständige Unterstützung 5.0nodejs Vollständige Unterstützung Ja
Spread in object literals
Experimentell
Chrome Vollständige Unterstützung 60Edge Keine Unterstützung NeinFirefox Vollständige Unterstützung 55IE Keine Unterstützung NeinOpera ? Safari Keine Unterstützung NeinWebView Android Vollständige Unterstützung 60Chrome Android Vollständige Unterstützung 60Edge Mobile Keine Unterstützung NeinFirefox Android Vollständige Unterstützung 55Opera Android ? Safari iOS Keine Unterstützung NeinSamsung Internet Android Keine Unterstützung Neinnodejs Vollständige Unterstützung 8.3.0
Vollständige Unterstützung 8.3.0
Vollständige Unterstützung 8.0.0
Deaktiviert
Deaktiviert From version 8.0.0: this feature is behind the --harmony runtime flag.

Legende

Vollständige Unterstützung  
Vollständige Unterstützung
Keine Unterstützung  
Keine Unterstützung
Kompatibilität unbekannt  
Kompatibilität unbekannt
Experimentell. Das Verhalten kann sich zukünftig ändern.
Experimentell. Das Verhalten kann sich zukünftig ändern.
Benutzer muss dieses Feature explizit aktivieren.
Benutzer muss dieses Feature explizit aktivieren.

Siehe auch

Schlagwörter des Dokuments und Mitwirkende

Mitwirkende an dieser Seite: shaedrich, schlagi123, mschleeweiss
Zuletzt aktualisiert von: shaedrich,