迴圈巢狀物件可以轉json嗎
什麼是迴圈引用?
迴圈引用是指一系列的引用,一個物件直接或者間接地透過一系列物件引用自己,導致閉環,大多數計算機語言都存在迴圈引用,包括 JavaScript。
JavaScript 中的迴圈引用
直接迴圈引用
上述定了一個名為 circularReference 的物件,它含有一個名為 myself 的屬性,而它的值又指向了這個物件,形成了迴圈引用。
間接迴圈引用
在上述程式碼中,我們建立了兩個物件 ObjectA 和 ObjectB,二者均有一個名為 link 的屬性,它的值都設定為對方的引用,這樣便形成了間接的迴圈引用。當我們在控制檯列印 ObjectA 時可以清晰地看到這一點。
陣列中的迴圈引用
在 JavaScript 中陣列是一種物件,也會有迴圈引用的現象。
JSON 格式不支援物件迴圈引用
目前 JSON 格式不支援物件引用,如果用 JSON。stringify() 嘗試把一個含有迴圈引用的物件轉成字串,會丟擲一個 TypeError。
解決方案
方案
1.
使用
JSON.stringify()
的
replacer
引數
JSON。stringify() 第二個可選引數 replacer 可以設定為一個函式或陣列。我們可以選擇設定為一個函式,在其中過濾掉迴圈引用(這樣會造成資料丟失):
在上述程式碼的 getCircularReplacer 函式中,我們藉助 ES6 的 WeakSet 實現了物件屬性值的濾重,從而避免了迴圈引用的問題。不過需要注意的是會造成資料丟失,物件中的引用關係被忽略,
但同時所有重複的物件值會被刪除。
如果 getCircularReplacer 函式應用到含有引用的陣列上,會發生什麼呢?
從上圖可以看到陣列中的引用被替換為了 null。這是由於在 replacer 函式中當屬性值為引用時返回了 undefined,而 undefined 不是有效的 JSON 值。如果在轉換過程中遇到了 undefined 這種無效值,它們被忽略(如果是在物件裡)或者被替換為 null (如果是在數組裡)。
方案
2.
使用
cycle.js
Douglas Crockford 是 JSON 的建立者,他也注意到了迴圈引用的問題,所以在 GitHub 上提供了 cycle。js 這個庫,它允許你把幾乎所有資料結構都可以轉成字串。
要把上述字串還原為原始的物件,可以使用 retrocycle 方法,使用方法是 JSON。retrocycle(JSON。parse(str))。所以可以保留物件中的引用關係。
主要注意的是 cycle。js 內部使用了 ES6 的 WeakMap 特性,以及 ES5 的許多特性,如果支援舊版瀏覽器同樣需要引入額外的相容庫。