Tiefe Kopien in JavaScript mit structuredClone
Ein Spread `{...obj}` kopiert nur die oberste Ebene – verschachtelte Objekte teilen sich weiter denselben Speicher. structuredClone macht eine echte tiefe Kopie, eingebaut und ohne JSON-Umweg.
Ein häufiger, tückischer Bug: Du kopierst ein Objekt mit {...obj}, änderst die Kopie – und plötzlich ändert sich auch das Original. Der Grund: Spread kopiert nur eine Ebene tief. Verschachtelte Objekte und Arrays sind in beiden weiterhin dieselben.
Das Problem
const original = { name: 'Kel', adresse: { stadt: 'Berlin' } };
const kopie = { ...original };
kopie.adresse.stadt = 'Hamburg';
original.adresse.stadt; // "Hamburg" – aua, Original mitverändert!Die Lösung: structuredClone
structuredClone ist eingebaut (moderne Browser + Node ≥ 17) und kopiert rekursiv – jede Ebene bekommt eigene Objekte:
const kopie = structuredClone(original);
kopie.adresse.stadt = 'Hamburg';
original.adresse.stadt; // "Berlin" – Original bleibt unberührtAnders als der alte Trick JSON.parse(JSON.stringify(obj)) kann structuredClone auch Date, Map, Set und ArrayBuffer – und es verkraftet sogar zyklische Referenzen (ein Objekt, das auf sich selbst zeigt), an denen JSON scheitert.
Eine Grenze gibt es: Funktionen und Klassen-Instanzen (Prototyp-Ketten) lassen sich nicht klonen – dann wirft es einen DataCloneError. Für reine Daten – Formularzustände, API-Antworten, Konfigurationen – ist es aber die sauberste Wahl.
Faustregel: Willst du einen Zustand kopieren, um ihn gefahrlos zu verändern (etwa in React/Vuex), ist structuredClone das ehrlichste Werkzeug dafür.
Solche Fallstricke früh zu kennen spart später Stunden Fehlersuche. Wenn du eine solide gebaute Website brauchst: bymw.de.
Quellen
Du brauchst mehr als ein Snippet?
Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.
Projekt anfragen →Verwandte Snippets
toSorted, toReversed und with: Arrays sortieren, ohne das Original zu zerstören
array.sort() sortiert nicht eine Kopie, sondern das Array selbst – und genau daran ist schon mancher Zustand im Frontend stillschweigend kaputtgegangen. Seit ES2023 gibt es zu jeder dieser Methoden eine Variante, die eine Kopie zurückgibt.
Aufzählungen richtig verketten mit Intl.ListFormat
"a, b und c" von Hand zusammenzubauen geht fast immer schief – bei einem Element, bei zwei Elementen, beim letzten Komma. Intl.ListFormat macht es richtig, in jeder Sprache, ganz ohne Bibliothek.
requestAnimationFrame – die Animationsschleife, die zum Bildschirm passt
setInterval(schritt, 16) läuft auf einem 144-Hz-Monitor anders als auf einem alten Handy – und im Hintergrundtab einfach weiter. requestAnimationFrame löst beides, wenn man die verstrichene Zeit mitrechnet statt Bilder zu zählen.