[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Operators/Spread_syntax [Back]  [Original]

Spread-Syntax (...) - JavaScript | MDN

Dieser Inhalt wurde automatisch aus dem Englischen bersetzt, und kann Fehler enthalten. Erfahre mehr ber dieses Experiment.

View in English Always switch to English

Spread-Syntax (...)

Baseline Weitgehend verfgbar

Diese Funktion ist gut etabliert und funktioniert auf vielen Gerten und in vielen Browserversionen. Sie ist seit Oktober 2015 browserbergreifend verfgbar.

Die Spread-Syntax (...) ermglicht es, ein Iterables, wie ein Array oder einen String, an Stellen zu erweitern, an denen null oder mehr Argumente (bei Funktionsaufrufen) oder Elemente (bei Array-Literalen) erwartet werden. In einem Objektliteral enumeriert die Spread-Syntax die Eigenschaften eines Objekts und fgt die Schlssel-Wert-Paare dem erstellten Objekt hinzu.

Die Spread-Syntax sieht genau wie die Rest-Syntax aus. In gewisser Weise ist die Spread-Syntax das Gegenteil der Rest-Syntax. Die Spread-Syntax "erweitert" ein Array in seine Elemente, whrend die Rest-Syntax mehrere Elemente sammelt und in ein einziges Element "kondensiert". Siehe Restparameter und Rest-Eigenschaft.

In diesem Artikel

Probieren Sie es aus

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

const numbers = [1, 2, 3];

console.log(sum(...numbers));
// Expected output: 6

console.log(sum.apply(null, numbers));
// Expected output: 6

Syntax

js
myFunction(a, ...iterableObj, b)
[1, ...iterableObj, '4', 'five', 6]
{ ...obj, key: 'value' }

Beschreibung

Spread-Syntax kann verwendet werden, wenn alle Elemente aus einem Objekt oder Array in einem neuen Array oder Objekt enthalten sein sollen oder einzeln in einer Argumentenliste eines Funktionsaufrufs angewendet werden sollen. Es gibt drei verschiedene Orte, die die Spread-Syntax akzeptieren:

Obwohl die Syntax gleich aussieht, haben sie leicht unterschiedliche Semantiken.

Nur iterable Werte, wie Array und String, knnen in Array-Literalen und Argumentenlisten erweitert werden. Viele Objekte sind nicht iterierbar, einschlielich aller einfachen Objekte, die keine Symbol.iterator Methode besitzen:

js
const obj = { key1: "value1" };
const array = [...obj]; // TypeError: obj is not iterable

Andererseits enumeriert das Erweitern in Objektliteralen die eigenen Eigenschaften des Werts. Bei typischen Arrays sind alle Indizes aufzhlbare eigene Eigenschaften, sodass Arrays in Objekte bertragen werden knnen.

js
const array = [1, 2, 3];
const obj = { ...array }; // { 0: 1, 1: 2, 2: 3 }

Alle Primitive knnen in Objekten erweitert werden. Nur Strings haben aufzhlbare eigene Eigenschaften, und das Erweitern von allem anderen erstellt keine Eigenschaften im neuen Objekt.

js
const obj = { ...true, ..."test", ...10 };
// { '0': 't', '1': 'e', '2': 's', '3': 't' }

Wenn Sie die Spread-Syntax fr Funktionsaufrufe verwenden, beachten Sie die Mglichkeit, das Argumentlngenlimit der JavaScript-Engine zu berschreiten. Siehe Function.prototype.apply() fr weitere Details.

Beispiele

Spread in Funktionsaufrufen

Apply() ersetzen

Es ist blich, Function.prototype.apply() in Fllen zu verwenden, in denen Sie die Elemente eines Arrays als Argumente an eine Funktion bergeben mchten.

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

Mit Spread-Syntax kann das oben stehende wie folgt geschrieben werden:

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

Jedes Argument in der Argumentenliste kann die Spread-Syntax verwenden, und die Spread-Syntax kann mehrmals verwendet werden.

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

Apply fr den new-Operator

Beim Aufrufen eines Konstruktors mit new ist es nicht mglich, ein Array und apply() direkt zu verwenden, da apply() die Zielmethode aufruft, anstatt sie zu konstruieren, was unter anderem bedeutet, dass new.target undefined sein wird. Dank der Spread-Syntax kann ein Array jedoch problemlos mit new verwendet werden:

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

Spread in Array-Literalen

Ein mchtigeres Array-Literal

Ohne Spread-Syntax reicht die Array-Literal-Syntax nicht mehr aus, um ein neues Array mit einem vorhandenen Array als Teil davon zu erstellen. Stattdessen muss imperativer Code verwendet werden, der eine Kombination aus Methoden wie push(), splice(), concat() usw. beinhaltet. Mit Spread-Syntax wird dies viel knapper:

js
const parts = ["shoulders", "knees"];
const lyrics = ["head", ...parts, "and", "toes"];
//  ["head", "shoulders", "knees", "and", "toes"]

Genau wie bei der Spread-Syntax fr Argumentenlisten kann ... berall im Array-Literal verwendet werden und kann mehrmals verwendet werden.

Kopieren eines Arrays

Sie knnen die Spread-Syntax verwenden, um eine flache Kopie eines Arrays zu erstellen. Jedes Array-Element behlt seine Identitt bei, ohne kopiert zu werden.

js
const arr = [1, 2, 3];
const arr2 = [...arr]; // like arr.slice()

arr2.push(4);
// arr2 becomes [1, 2, 3, 4]
// arr remains unaffected

Die Spread-Syntax geht effektiv eine Ebene tief beim Kopieren eines Arrays. Daher ist sie mglicherweise nicht geeignet zum Kopieren mehrdimensionaler Arrays. Dasselbe gilt fr Object.assign() keine native Operation in JavaScript fhrt ein Deep-Klonen durch. Die Web-API-Methode structuredClone() ermglicht das tiefe Kopieren von Werten bestimmter untersttzter Typen. Weitere Details finden Sie unter flache Kopie.

js
const a = [[1], [2], [3]];
const b = [...a];

b.shift().shift();
// 1

// Oh no! Now array 'a' is affected as well:
console.log(a);
// [[], [2], [3]]

Ein besserer Weg, um Arrays zu verketten

Array.prototype.concat() wird oft verwendet, um ein Array an das Ende eines bestehenden Arrays anzufgen. Ohne Spread-Syntax wird dies so gemacht:

js
let arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];

// Append all items from arr2 onto arr1
arr1 = arr1.concat(arr2);

Mit Spread-Syntax wird daraus:

js
let arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];

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

Array.prototype.unshift() wird oft verwendet, um ein Array von Werten am Anfang eines bestehenden Arrays einzufgen. Ohne Spread-Syntax wird dies so gemacht:

js
const arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];

//  Prepend all items from arr2 onto arr1
Array.prototype.unshift.apply(arr1, arr2);
console.log(arr1); // [3, 4, 5, 0, 1, 2]

Mit Spread-Syntax wird daraus:

js
let arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];

arr1 = [...arr2, ...arr1];
console.log(arr1); // [3, 4, 5, 0, 1, 2]

Hinweis: Im Gegensatz zu unshift() wird hierbei ein neues arr1 erstellt, anstatt das ursprngliche Array arr1 direkt zu verndern.

Bedingtes Hinzufgen von Werten zu einem Array

Sie knnen ein Element in einem Array-Literal abhngig von einer Bedingung vorhanden oder abwesend machen, indem Sie einen Bedingungsoperator verwenden.

js
const isSummer = false;
const fruits = ["apple", "banana", ...(isSummer ? ["watermelon"] : [])];
// ['apple', 'banana']

Wenn die Bedingung false ist, erweitern wir ein leeres Array, sodass nichts zum endgltigen Array hinzugefgt wird. Beachten Sie, dass dies anders ist als Folgendes:

js
const fruits = ["apple", "banana", isSummer ? "watermelon" : undefined];
// ['apple', 'banana', undefined]

In diesem Fall wird ein zustzliches undefined-Element hinzugefgt, wenn isSummer false ist, und dieses Element wird von Methoden wie Array.prototype.map() besucht.

Spread in Objekt-Literalen

Kopieren und Zusammenfhren von Objekten

Sie knnen die Spread-Syntax verwenden, um mehrere Objekte in einem neuen Objekt zusammenzufhren.

js
const obj1 = { foo: "bar", x: 42 };
const obj2 = { bar: "baz", y: 13 };

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

Ein einzelnes Spread erstellt eine flache Kopie des ursprnglichen Objekts (aber ohne nicht-auflistbare Eigenschaften und ohne das Prototypenobjekt zu kopieren), hnlich wie beim Kopieren eines Arrays.

js
const clonedObj = { ...obj1 };
// { foo: "bar", x: 42 }

berschreiben von Eigenschaften

Wenn ein Objekt in ein anderes Objekt erweitert wird, oder wenn mehrere Objekte in ein Objekt erweitert werden und dabei Eigenschaften mit identischen Namen aufeinandertreffen, nimmt die Eigenschaft den zuletzt zugewiesenen Wert an und bleibt an der Position, an der sie ursprnglich gesetzt wurde.

js
const obj1 = { foo: "bar", x: 42 };
const obj2 = { foo: "baz", y: 13 };

const mergedObj = { x: 41, ...obj1, ...obj2, y: 9 }; // { x: 42, foo: "baz", y: 9 }

Bedingtes Hinzufgen von Eigenschaften zu einem Objekt

Sie knnen ein Element in einem Objektliteral abhngig von einer Bedingung vorhanden oder abwesend machen, indem Sie einen Bedingungsoperator verwenden.

js
const isSummer = false;
const fruits = {
  apple: 10,
  banana: 5,
  ...(isSummer ? { watermelon: 30 } : {}),
};
// { apple: 10, banana: 5 }

Der Fall, in dem die Bedingung false ist, ist ein leeres Objekt, so dass nichts in das endgltige Objekt erweitert wird. Beachten Sie, dass dies anders ist als Folgendes:

js
const fruits = {
  apple: 10,
  banana: 5,
  watermelon: isSummer ? 30 : undefined,
};
// { apple: 10, banana: 5, watermelon: undefined }

In diesem Fall ist die watermelon-Eigenschaft immer vorhanden und wird von Methoden wie Object.keys() besucht.

Da auch Primitive in Objekte erweitert werden knnen, und aus der Beobachtung heraus, dass alle falsy Werte keine auflistbaren Eigenschaften besitzen, knnen Sie einfach einen logischen UND Operator verwenden:

js
const isSummer = false;
const fruits = {
  apple: 10,
  banana: 5,
  ...(isSummer && { watermelon: 30 }),
};

In diesem Fall, wenn isSummer irgendein falsy Wert ist, wird keine Eigenschaft im fruits-Objekt erstellt.

Vergleich mit Object.assign()

Beachten Sie, dass Object.assign() verwendet werden kann, um ein Objekt zu verndern, whrend die Spread-Syntax dies nicht kann.

js
const obj1 = { foo: "bar", x: 42 };
Object.assign(obj1, { x: 1337 });
console.log(obj1); // { foo: "bar", x: 1337 }

Zustzlich lst Object.assign() Setter auf dem Zielobjekt aus, whrend die Spread-Syntax dies nicht tut.

js
const objectAssign = Object.assign(
  {
    set foo(val) {
      console.log(val);
    },
  },
  { foo: 1 },
);
// Logs "1"; objectAssign.foo is still the original setter

const spread = {
  set foo(val) {
    console.log(val);
  },
  ...{ foo: 1 },
};
// Nothing is logged; spread.foo is 1

Sie knnen die Object.assign() Funktion nicht naiv durch ein einfaches Erweitern nachbilden:

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

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

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

Im obigen Beispiel funktioniert die Spread-Syntax nicht wie erwartet: Sie erweitert ein Array von Argumenten in das Objektliteral, aufgrund des Restparameters. Hier ist eine Implementierung von merge mit der Spread-Syntax, deren Verhalten hnlich wie Object.assign() ist, auer dass sie keine Setter auslst, noch irgendein Objekt verndert:

js
const obj1 = { foo: "bar", x: 42 };
const obj2 = { foo: "baz", y: 13 };
const merge = (...objects) =>
  objects.reduce((acc, cur) => ({ ...acc, ...cur }));

const mergedObj = merge(obj1, obj2);
// { foo: 'baz', x: 42, y: 13 }

Spezifikationen

Spezifikation
ECMAScript 2027 LanguageSpecification
# prod-SpreadElement
ECMAScript 2027 LanguageSpecification
# prod-ArgumentList
ECMAScript 2027 LanguageSpecification
# prod-PropertyDefinition

Browser-Kompatibilitt

Siehe auch


Web Proxy Viewer  |  New URL  |  Original Page