首頁 > 易卦

解決JSON中迴圈引用的問題

作者:由 小象Web開發 發表于 易卦日期:2022-10-05

迴圈巢狀物件可以轉json嗎

解決JSON中迴圈引用的問題

什麼是迴圈引用?

迴圈引用是指一系列的引用,一個物件直接或者間接地透過一系列物件引用自己,導致閉環,大多數計算機語言都存在迴圈引用,包括 JavaScript。

JavaScript 中的迴圈引用

直接迴圈引用

解決JSON中迴圈引用的問題

上述定了一個名為 circularReference 的物件,它含有一個名為 myself 的屬性,而它的值又指向了這個物件,形成了迴圈引用。

間接迴圈引用

解決JSON中迴圈引用的問題

在上述程式碼中,我們建立了兩個物件 ObjectA 和 ObjectB,二者均有一個名為 link 的屬性,它的值都設定為對方的引用,這樣便形成了間接的迴圈引用。當我們在控制檯列印 ObjectA 時可以清晰地看到這一點。

陣列中的迴圈引用

在 JavaScript 中陣列是一種物件,也會有迴圈引用的現象。

解決JSON中迴圈引用的問題

JSON 格式不支援物件迴圈引用

目前 JSON 格式不支援物件引用,如果用 JSON。stringify() 嘗試把一個含有迴圈引用的物件轉成字串,會丟擲一個 TypeError。

解決JSON中迴圈引用的問題

解決方案

方案

1.

使用

JSON.stringify()

replacer

引數

JSON。stringify() 第二個可選引數 replacer 可以設定為一個函式或陣列。我們可以選擇設定為一個函式,在其中過濾掉迴圈引用(這樣會造成資料丟失):

解決JSON中迴圈引用的問題

在上述程式碼的 getCircularReplacer 函式中,我們藉助 ES6 的 WeakSet 實現了物件屬性值的濾重,從而避免了迴圈引用的問題。不過需要注意的是會造成資料丟失,物件中的引用關係被忽略,

但同時所有重複的物件值會被刪除。

如果 getCircularReplacer 函式應用到含有引用的陣列上,會發生什麼呢?

解決JSON中迴圈引用的問題

從上圖可以看到陣列中的引用被替換為了 null。這是由於在 replacer 函式中當屬性值為引用時返回了 undefined,而 undefined 不是有效的 JSON 值。如果在轉換過程中遇到了 undefined 這種無效值,它們被忽略(如果是在物件裡)或者被替換為 null (如果是在數組裡)。

方案

2.

使用

cycle.js

Douglas Crockford 是 JSON 的建立者,他也注意到了迴圈引用的問題,所以在 GitHub 上提供了 cycle。js 這個庫,它允許你把幾乎所有資料結構都可以轉成字串。

解決JSON中迴圈引用的問題

要把上述字串還原為原始的物件,可以使用 retrocycle 方法,使用方法是 JSON。retrocycle(JSON。parse(str))。所以可以保留物件中的引用關係。

主要注意的是 cycle。js 內部使用了 ES6 的 WeakMap 特性,以及 ES5 的許多特性,如果支援舊版瀏覽器同樣需要引入額外的相容庫。