TypeError: cyclic object value

Die JavaScript-Ausnahme "cyclic object value" tritt auf, wenn Objektverweise in JSON gefunden werden. JSON.stringify() versucht nicht, diese zu lösen, und schlägt dementsprechend fehl.

Nachricht

TypeError: Converting circular structure to JSON (V8-based)
TypeError: cyclic object value (Firefox)
TypeError: JSON.stringify cannot serialize cyclic structures. (Safari)

Fehlertyp

Was ist schiefgelaufen?

Das JSON-Format unterstützt an sich keine Objektverweise (obwohl ein IETF-Draft existiert), daher versucht JSON.stringify() nicht, diese zu lösen und schlägt dementsprechend fehl.

Beispiele

Zirkuläre Referenzen

In einer zirkulären Struktur wie der folgenden

js
const circularReference = { otherData: 123 };
circularReference.myself = circularReference;

wird JSON.stringify() fehlschlagen

js
JSON.stringify(circularReference);
// TypeError: cyclic object value

Um zirkuläre Referenzen zu serialisieren, können Sie eine Bibliothek verwenden, die diese unterstützt (z. B. cycle.js) oder eine eigene Lösung implementieren, welche erfordert, die zirkulären Referenzen durch serialisierbare Werte zu finden und zu ersetzen (oder zu entfernen).

Das folgende Snippet veranschaulicht, wie man eine zirkuläre Referenz durch Verwendung des replacer-Parameters von JSON.stringify() findet und filtert (was zu Datenverlust führt):

js
function getCircularReplacer() {
  const ancestors = [];
  return function (key, value) {
    if (typeof value !== "object" || value === null) {
      return value;
    }
    // `this` is the object that value is contained in,
    // i.e., its direct parent.
    while (ancestors.length > 0 && ancestors.at(-1) !== this) {
      ancestors.pop();
    }
    if (ancestors.includes(value)) {
      return "[Circular]";
    }
    ancestors.push(value);
    return value;
  };
}

JSON.stringify(circularReference, getCircularReplacer());
// {"otherData":123,"myself":"[Circular]"}

const o = {};
const notCircularReference = [o, o];
JSON.stringify(notCircularReference, getCircularReplacer());
// [{},{}]

Siehe auch