TypeError: cyclic object value

當在 JSON 中發現物件引用時,會發生 JavaScript 異常 "cyclic object value"。 JSON.stringify() 不會嘗試解決它們,並因此失敗。

訊息

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

錯誤型別

TypeError

哪裡出錯了?

JSON 格式本身不支援物件引用(儘管存在 IETF 草案),因此 JSON.stringify() 不會嘗試解決它們,並因此失敗。

示例

迴圈引用

在以下迴圈結構中

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

JSON.stringify() 將失敗

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

要序列化迴圈引用,可以使用支援它們的庫(例如,cycle.js),或者自己實現一個解決方案,這需要透過可序列化值查詢和替換(或刪除)迴圈引用。

下面的程式碼片段演示瞭如何使用 JSON.stringify()replacer 引數查詢和過濾(從而導致資料丟失)迴圈引用。

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());
// [{},{}]

另見