Menu

Spread- und Rest-Operator in JavaScript erklärt

Wie der ...-Operator in JavaScript wirklich funktioniert: Argumente mit Rest-Parametern einsammeln, Arrays und Objekte per Spread entpacken – und wann du was brauchst.

Gleiche Syntax, zwei Aufgaben

Die drei Punkte ... begegnen dir in modernem JavaScript ständig – und sie erfüllen je nach Position zwei komplett gegensätzliche Aufgaben. Wenn du das Muster einmal erkannt hast, fällt jede Verwendung von ... in eine von zwei Schubladen:

  • Rest: ...name auf der empfangenden Seite sammelt mehrere Werte in einem Array oder Objekt.
  • Spread: ...value auf der gebenden Seite zerlegt ein Array oder Objekt in seine einzelnen Bestandteile.

Das ist im Grunde das ganze mentale Modell – der Rest dieser Seite sind nur Beispiele dazu und die Muster, die du immer wieder brauchen wirst.

Rest-Parameter: Argumente einsammeln

Ein Rest-Parameter in einer Funktionsdefinition fängt beliebig viele Argumente ein und packt sie in ein echtes Array:

index.js
Output
Click Run to see the output here.

nums ist ein ganz normales Array. Du kannst .map darauf anwenden, .filter nutzen, die .length abfragen oder es an andere Funktionen weitergeben – eben alles, was Arrays so können.

Rest-Parameter lassen sich auch mit normalen Parametern kombinieren, der Rest-Parameter muss dabei aber immer an letzter Stelle stehen:

index.js
Output
Click Run to see the output here.

label schnappt sich das erste Argument, alles Weitere landet in items. Den Rest-Parameter irgendwo anders als an letzter Stelle zu schreiben, ist ein Syntaxfehler.

Rest-Parameter vs. das alte arguments-Objekt

Älterer JavaScript-Code greift innerhalb normaler Funktionen auf eine magische Variable namens arguments zurück. Die sieht zwar wie ein Array aus, ist aber keins – Array-Methoden funktionieren darauf also nicht direkt. Rest-Parameter lösen das Problem sauber:

index.js
Output
Click Run to see the output here.

Arrow Functions besitzen nicht einmal ein arguments-Objekt – Rest Parameter sind dort also die einzige Möglichkeit, eine variable Anzahl an Argumenten entgegenzunehmen. In neuem Code solltest du konsequent auf ...args setzen.

Spread Operator beim Funktionsaufruf

Der Spread Operator macht beim Aufruf genau das Gegenteil: Er nimmt ein Array und packt es an der Aufrufstelle in einzelne Argumente aus.

index.js
Output
Click Run to see the output here.

Math.max erwartet einzelne Zahlen, kein Array. Vor dem Spread-Operator musste man Math.max.apply(null, nums) schreiben. Heute reicht ein ... – fertig.

Beachte: Genau dasselbe ... ist in der Funktions_definition_ ein Rest-Parameter und im Funktions_aufruf_ der Spread-Operator – die Position entscheidet, welches von beiden gemeint ist.

Spread Operator in Array-Literalen

Mit dem Spread-Operator lassen sich Arrays in einem Array-Literal kopieren oder zusammenführen:

index.js
Output
Click Run to see the output here.

[...a] erzeugt ein frisches Array mit denselben Elementen – praktisch, wenn du sortieren oder verändern willst, ohne das Original anzufassen:

index.js
Output
Click Run to see the output here.

scores bleibt unverändert, weil .sort auf der Kopie läuft. Eine kleine Angewohnheit mit großem Effekt – besonders, wenn dein Code keine überraschenden Seiteneffekte produzieren soll.

Spread Operator bei Objekt-Literalen

Der Spread Operator funktioniert auch mit gewöhnlichen Objekten und fügt deren Eigenschaften zu einem neuen Objekt zusammen:

index.js
Output
Click Run to see the output here.

Der letzte Key gewinnt. updates.age überschreibt also user.age, und city kommt einfach mit dazu. Die Reihenfolge der Spreads bestimmt das Ergebnis – daran solltest du denken, wenn du Defaults und Overrides übereinanderstapelst:

index.js
Output
Click Run to see the output here.

Standardwerte zuerst, dann die Auswahl des Users. Bei fontSize gewinnt der User, das theme wird geerbt.

Die Falle beim Shallow Copy

Der Spread Operator kopiert nur eine Ebene tief. Verschachtelte Objekte und Arrays teilen sich Original und Kopie weiterhin:

index.js
Output
Click Run to see the output here.

Beide Arrays enthalten das neue Tag, weil copy.tags und original.tags auf dasselbe Array verweisen. Der Spread-Operator hat die verschachtelte Liste also gar nicht geklont — er hat nur die Referenz übernommen.

Für eine echte Tiefenkopie (Deep Copy) von reinen Daten greifst du am besten zu structuredClone:

index.js
Output
Click Run to see the output here.

Damit sind beide Arrays voneinander entkoppelt. structuredClone ist in modernen Browsern und in Node bereits eingebaut, kommt auch mit verschachtelten Strukturen klar und ist die richtige Wahl, sobald ein Shallow Copy nicht mehr reicht.

Rest beim Destructuring

Der Rest-Parameter funktioniert auch beim Destructuring – dort fängt er alle übrig gebliebenen Elemente oder Eigenschaften ein:

index.js
Output
Click Run to see the output here.

Ein paar Felder rauspicken und den Rest in einem einzigen Objekt behalten – dieses Muster begegnet dir ständig: beim Weiterreichen von Props, beim Entfernen sensibler Felder oder wenn du gepatchte Versionen deiner Daten bauen willst:

index.js
Output
Click Run to see the output here.

password wird herausgezogen (und ignoriert), safe enthält den ganzen Rest. Keine Mutation, kein manuelles Kopieren.

Kurze Zusammenfassung

  • ...name in einer Parameterliste oder einem Destrukturierungsmuster ist Rest: es sammelt ein.
  • ...value in einem Funktionsaufruf, Array-Literal oder Objekt-Literal ist Spread: es expandiert.
  • Kopien per Spread sind flach (shallow copy). Verschachtelte Strukturen bleiben geteilt. Für echte Deep Copies nimmst du structuredClone.
  • Rest-Parameter sind echte Arrays — nutze sie statt arguments.
  • In Objekt-Literalen überschreiben spätere Spreads frühere. Genau so baut man das Muster „Defaults plus Overrides".

Als Nächstes: Closures

Funktionen in JavaScript nehmen nicht nur Eingaben entgegen und geben Werte zurück — sie merken sich auch den Scope, in dem sie definiert wurden. Dieses Gedächtnis nennt man Closure, und es steckt hinter Callbacks, Factories und den meisten Patterns, die dir auf der nächsten Seite begegnen.

Häufig gestellte Fragen

Was ist der Unterschied zwischen Rest und Spread in JavaScript?

Beide schreiben sich ..., machen aber genau das Gegenteil. Rest sammelt mehrere Werte in einem einzigen Array – typisch in Parameterlisten und beim Destructuring. Spread entpackt ein Iterable oder Objekt in seine Einzelteile – also bei Funktionsaufrufen, Array-Literalen und Objekt-Literalen. Faustregel: Steht ... auf der empfangenden Seite, ist es Rest. Steht es auf der gebenden Seite, ist es Spread.

Wie funktionieren Rest-Parameter in einer Funktion?

Ein Rest-Parameter wie function sum(...nums) packt alle übergebenen Argumente in ein echtes Array namens nums. Wichtig: Er muss immer der letzte Parameter sein. Im Gegensatz zum alten arguments-Objekt ist ein Rest-Parameter ein vollwertiges Array – du kannst also direkt .map, .filter oder .reduce darauf aufrufen.

Erzeugt der Spread-Operator eine tiefe Kopie?

Nein. Spread kopiert nur eine Ebene – es ist also eine flache Kopie (shallow copy). { ...user } liefert dir zwar ein neues Objekt mit denselben Top-Level-Keys, aber verschachtelte Objekte und Arrays zeigen weiterhin auf dieselben Referenzen. Für eine echte Tiefenkopie nimmst du structuredClone(value) oder – bei reinen Daten – den Umweg über JSON.parse(JSON.stringify(...)).

Lerne mit Coddy zu programmieren

LOS GEHT'S