Start · Sprachen · JavaScript · Referenz · Window.structuredClone()

Window.structuredClone()

Methode

Erstellt mit dem Structured-Clone-Algorithmus eine tiefe Kopie eines Wertes. Übertragbare Objekte können dabei optional übertragen statt kopiert werden.

seit JavaScript Baseline 2022: Chrome 98, Firefox 94, Safari 15.4, Kategorie: webapi

Signatur

structuredClone(value, options)

Beschreibung

structuredClone() ist eine globale Funktion und steht in Window, in Workern und in Node.js zur Verfügung. Sie erstellt eine tiefe Kopie eines Wertes. Dafür nutzt sie denselben Algorithmus, mit dem Browser auch Daten für postMessage(), IndexedDB oder history.pushState() serialisieren. Verschachtelte Objekte und Arrays werden vollständig kopiert. Änderungen an der Kopie wirken sich also nicht auf das Original aus.

Der klassische Trick JSON.parse(JSON.stringify(obj)) hat mehrere Schwächen. structuredClone() behebt sie:

  • Date, Map, Set, RegExp, ArrayBuffer, typisierte Arrays, Blob, File und ImageData bleiben erhalten.
  • Zirkuläre Referenzen und mehrfach verwendete Referenzen werden korrekt nachgebildet.
  • Die Werte undefined, NaN, Infinity und BigInt gehen nicht verloren.

Mit der Option transfer lassen sich übertragbare Objekte (z. B. ArrayBuffer, MessagePort, ImageBitmap) an die Kopie übergeben, ohne sie zu kopieren. Das ist bei großen Binärdaten sehr schnell. Das Original wird dabei jedoch unbrauchbar („detached“).

Nicht alles lässt sich klonen. Funktionen, DOM-Knoten und manche Plattform-Objekte führen zu einer DataCloneError-DOMException. Klasseninstanzen verlieren ihren Prototyp und werden zu einfachen Objekten.

Parameter

Name Typ Default Beschreibung
$value Pflicht any Der zu klonende Wert. Das können primitive Werte, einfache Objekte und Arrays sowie alle vom Structured-Clone-Algorithmus unterstützten Typen sein.
$options { transfer?: Transferable[] } {} Optionales Objekt mit der Eigenschaft transfer. Das ist ein Array übertragbarer Objekte, die in die Kopie verschoben statt kopiert werden.

Rückgabewert

Typ
any
Beschreibung
Eine tiefe Kopie von value. Primitive Werte werden unverändert zurückgegeben.

Beispiele

Verschachteltes Objekt mit Date und Map tief kopieren

const original = {
  titel: 'Bestellung',
  erstellt: new Date('2024-05-01'),
  positionen: new Map([['A1', { menge: 2 }]]),
  tags: new Set(['neu'])
};

const kopie = structuredClone(original);
kopie.positionen.get('A1').menge = 99;

console.log(original.positionen.get('A1').menge);
console.log(kopie.erstellt instanceof Date);
console.log(kopie.erstellt === original.erstellt);
2 true false

Zirkuläre Referenzen – JSON scheitert, structuredClone nicht

const knoten = { name: 'Wurzel' };
knoten.selbst = knoten;

try {
  JSON.stringify(knoten);
} catch (e) {
  console.log('JSON:', e.name);
}

const klon = structuredClone(knoten);
console.log(klon.selbst === klon);
console.log(klon === knoten);
JSON: TypeError true false

ArrayBuffer übertragen statt kopieren

const puffer = new Uint8Array(1024 * 1024).buffer; // 1 MB

const neu = structuredClone(puffer, { transfer: [puffer] });

console.log(neu.byteLength);
console.log(puffer.byteLength); // Original ist jetzt detached
1048576 0

Nicht klonbare Werte abfangen

const zustand = {
  zaehler: 1,
  onChange: () => console.log('geändert')
};

try {
  structuredClone(zustand);
} catch (e) {
  console.log(e.name);
}

// Workaround: Funktionen vorher entfernen
const { onChange, ...daten } = zustand;
console.log(structuredClone(daten));
DataCloneError { zaehler: 1 }

// Wichtig · Fallstricke

  • Funktionen, DOM-Knoten, Symbole als Werte und WeakMap/WeakSet sind nicht klonbar. Sie lösen eine DataCloneError-DOMException aus.
  • Der Prototyp geht verloren: Klasseninstanzen werden zu einfachen Objekten. Methoden, Getter/Setter und nicht aufzählbare Eigenschaften fehlen in der Kopie.
  • Die Werte von Eigenschafts-Deskriptoren werden kopiert, die Deskriptoren selbst (z. B. writable: false) nicht. Auch Object.freeze() wird nicht übernommen.
  • Symbol-Schlüssel werden ignoriert. RegExp.lastIndex wird nicht übernommen.
  • Fehlerobjekte (Error) werden in modernen Engines unterstützt. Der Stack-Trace bleibt dabei nicht überall erhalten.
  • Nach einem Transfer ist das Original unbrauchbar (byteLength ist dann 0). Ein erneuter Zugriff auf die Daten kann zu einem TypeError führen.
  • Kompatibilität: Die Funktion ist seit 2022 in allen modernen Browsern verfügbar, in Node.js ab Version 17. Für ältere Umgebungen gibt es einen Polyfill (z. B. core-js). Dieser kann aber nicht alle Typen und Transfers abbilden.
  • Performance: Bei kleinen, flachen Objekten sind Spread ({...obj}) oder JSON oft schneller. Die Stärke von structuredClone() liegt in Korrektheit und Typtreue.