Menu

JavaScript Spread Operator für Objekte: Klonen & Mergen

Wie der Spread-Operator bei Objekten in JavaScript wirklich funktioniert – Klonen, Mergen, Properties überschreiben und die typische Shallow-Copy-Falle.

Spread kopiert ein Objekt in ein anderes

Der Object-Spread-Operator in JavaScript – drei Punkte vor einem Objekt – übernimmt dessen eigene, aufzählbare Eigenschaften in das umgebende Objektliteral. Damit ist ...obj der kürzeste Weg, um in JavaScript ein Objekt zu klonen, Objekte zu mergen oder veränderte Kopien zu erzeugen, ohne das Original anzufassen.

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

copy hat die gleichen Keys und Values wie user, ist aber ein anderes Objekt. Wenn du das eine veränderst, bleibt das andere unberührt – zumindest auf der obersten Ebene. Auf diese Einschränkung kommen wir gleich noch zurück.

Das mentale Modell dahinter: { ...obj } bedeutet so viel wie „schütte die Properties von obj in dieses neue Objektliteral". Alles, was du zusätzlich zum Spread schreibst, landet ebenfalls im Ergebnis.

Objekt klonen und Properties überschreiben in einem Schritt

Das häufigste Muster beim Spread-Operator in JavaScript: ein Objekt spreaden und dabei einzelne Properties ergänzen oder überschreiben. Dabei gilt – der letzte Key gewinnt. Also erst spreaden, dann überschreiben:

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

user bleibt unangetastet. updated ist ein neues Objekt, bei dem role überschrieben wurde. Dieses Muster für immutable Updates begegnet dir heute überall in JavaScript – in React-State-Updatern, in Redux-Reducern und generell in Code, der Mutationen vermeiden will.

Drehst du die Reihenfolge um, passiert genau das Gegenteil:

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

Hier steht role: "guest" am Anfang und wird von user.role überschrieben. Praktisch, wenn du Default-Werte setzen willst, die das gespreadete Objekt dann überschreiben darf.

Objekte mergen in JavaScript

Um mehrere Objekte zusammenzuführen, spreadest du einfach zwei (oder mehr) Objekte in ein neues Objektliteral. Bei Schlüssel-Konflikten gewinnt das Objekt, das weiter hinten steht:

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

theme und fontSize kommen aus userPrefs, debug wird aus defaults durchgereicht. Drei Objekte? Vier? Die Regel bleibt gleich – von vorne nach hinten gelesen, der letzte Schreibvorgang gewinnt.

Das ist der moderne Ersatz für Object.assign({}, defaults, userPrefs). Beide Varianten machen dasselbe, aber die Spread-Variante ist angenehmer zu lesen und verleitet dich nicht zu dem klassischen Bug, Object.assign(defaults, userPrefs) zu schreiben – denn damit mutierst du defaults.

Spread erzeugt nur eine Shallow Copy

Hier tappen viele in die Falle. Der Spread Operator kopiert nur die Eigenschaften auf der obersten Ebene eines Objekts. Ist der Wert einer Eigenschaft selbst wieder ein Objekt oder ein Array, wird lediglich die Referenz übernommen – nicht der Inhalt.

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

Dass sich beim Ändern von copy.address.city auch user.address.city mitverändert, liegt daran, dass sich beide Objekte dasselbe address-Objekt teilen. Der Spread-Operator erzeugt nur eine neue äußere Hülle — also eine shallow copy.

Wenn du verschachtelte Werte anpassen willst, musst du jede Ebene, die du ändern möchtest, einzeln spreaden:

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

Für ein wirklich tiefes Klonen beliebiger Daten greifst du am besten zu structuredClone(obj). Die Funktion kommt mit verschachtelten Objekten, Arrays, Dates, Maps und Sets klar – und ist in jeder modernen Runtime direkt eingebaut.

Spread vs. Rest

Beide nutzen die gleichen drei Punkte, machen aber genau das Gegenteil. Spread entpackt, Rest sammelt ein.

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

Als Faustregel gilt: Steht das ... vor einem = (also beim Destrukturieren), handelt es sich um Rest. Taucht es dagegen innerhalb eines Objekt- oder Array-Literals nach dem = auf, ist es Spread.

Eine Eigenschaft immutabel entfernen

Wenn du Rest-Destrukturierung mit dem Spread-Operator kombinierst, bekommst du einen eleganten Weg, eine Kopie eines Objekts ohne einen bestimmten Key zu erzeugen – ganz ohne delete und ohne das Original zu verändern:

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

tempToken wird in eine eigene Variable gezogen (die du ignorierst), und alles andere landet in safe. Das ursprüngliche user bleibt unangetastet.

Was der Spread-Operator nicht kopiert

Ein paar Feinheiten, die man kennen sollte:

  • Nicht-enumerierbare Properties werden nicht kopiert. Die meisten Properties, die du selbst anlegst, sind standardmäßig enumerierbar – aber Properties, die mit Object.defineProperty definiert wurden, sowie bestimmte Built-ins sind es nicht.
  • Der Prototype wird nicht mitkopiert. { ...instance } liefert dir ein reines Objekt, keine Instanz der ursprünglichen Klasse. Methoden, die am Klassen-Prototype hängen, fehlen in der Kopie.
  • Getter werden ausgeführt. Wenn du ein Objekt mit einem Getter spreadest, wird der Getter einmal aufgerufen und der Rückgabewert als ganz normale Property im neuen Objekt abgelegt.
index.js
Output
Click Run to see the output here.

copy hat zwar x und y, ist aber nur ein schlichtes Objekt — distance liegt auf Point.prototype, und den hat der Spread-Operator gar nicht angefasst. Wenn du eine Klassen-Instanz wirklich klonen willst, muss die Klasse in der Regel selbst eine clone-Methode mitbringen.

Weiter geht's: Array-Methoden

Der Spread-Operator ist nur ein Baustein im Werkzeugkasten für unveränderliche Daten. Der andere große Baustein sind die Array-Methoden — map, filter, reduce und Konsorten — die neue Arrays erzeugen, statt die Originale zu verändern. Darum geht's auf der nächsten Seite.

Häufig gestellte Fragen

Was macht ...obj in JavaScript eigentlich?

Innerhalb eines Objektliterals kopiert ...obj alle eigenen, enumerierbaren Properties des Objekts in das neue Objekt. { ...user } liefert dir also ein frisches Objekt mit denselben Keys und Werten wie user. Das ist der Standardweg, um Objekte zu klonen oder zu mergen, ohne die Originale zu verändern.

Wie merge ich zwei Objekte in JavaScript?

Einfach beide in ein neues Objektliteral spreaden: const merged = { ...a, ...b }. Properties aus b überschreiben gleichnamige Keys aus a, denn der spätere Wert gewinnt. Das ist äquivalent zu Object.assign({}, a, b), liest sich aber deutlich sauberer.

Ist Object Spread eine Deep Copy?

Nein. Object Spread macht nur eine Shallow Copy – die Properties auf oberster Ebene werden kopiert, aber verschachtelte Objekte und Arrays bleiben per Referenz verknüpft. Wenn du copy.address.city änderst, ändert sich auch original.address.city. Für eine echte Deep Copy nimmst du structuredClone(obj).

Was ist der Unterschied zwischen Spread und Rest?

Syntaktisch sehen beide gleich aus (...), machen aber genau das Gegenteil. Spread verteilt ein Objekt oder Array in einzelne Properties bzw. Elemente: { ...user }. Rest dagegen sammelt den Rest in einer Variablen ein: const { name, ...others } = user. Der Kontext verrät dir immer, was gerade gemeint ist.

Lerne mit Coddy zu programmieren

LOS GEHT'S