Mam obiekt (drzewo parsowania), który zawiera węzły potomne, które są odniesieniami do innych węzłów.
Chciałbym serializować ten obiekt, używając JSON.stringify()
, ale otrzymuję
TypeError: cykliczna wartość obiektu
ze względu na konstrukcje, o których wspomniałem.
Jak mogłem to obejść? Nie ma dla mnie znaczenia, czy te odwołania do innych węzłów są reprezentowane, czy nie w serializowanym obiekcie.
Z drugiej strony usuwanie tych właściwości z obiektu podczas ich tworzenia wydaje się żmudne i nie chciałbym wprowadzać zmian w parserze (narcyz).
javascript
json
jsonserializer
stringify
Loic Duros
źródło
źródło
cycle.js
, ponieważ jest to najbardziej odpowiednie rozwiązanie w wielu przypadkach. Wydaje się właściwe, abyś opublikował tę odpowiedź, ponieważ jesteś pierwszą osobą, która się do niej odwołuje (w komentarzu poniżej). Jeśli nie masz ochoty publikować tego jako odpowiedzi, w końcu to zrobię.Odpowiedzi:
Użyj drugi parametr
stringify
, na funkcję zamiennika , aby wykluczyć już szeregowane obiekty:http://jsfiddle.net/mH6cJ/38/
Jak słusznie wskazano w innych komentarzach, kod ten usuwa każdy „widziany” obiekt, nie tylko „rekurencyjny”.
Na przykład dla:
wynik będzie nieprawidłowy. Jeśli twoja struktura jest taka, możesz chcieć użyć decyklu Crockforda lub tej (prostszej) funkcji, która po prostu zastępuje odwołania rekurencyjne zerami:
źródło
Stworzyłem GitHub Gist, który jest w stanie wykryć struktury cykliczne, a także je odkodować i zakodować: https://gist.github.com/Hoff97/9842228
Aby przekształcić po prostu użyj JSONE.stringify / JSONE.parse. Ponadto dekoduje i koduje funkcje. Jeśli chcesz to wyłączyć, po prostu usuń linie 32-48 i 61-85.
Przykładowe skrzypce znajdziesz tutaj:
http://jsfiddle.net/hoff97/7UYd4/
źródło
To jest rodzaj alternatywnej odpowiedzi, ale ponieważ wiele osób przyjdzie tutaj, to debugowanie ich okrągłych obiektów, a nie ma naprawdę świetnego sposobu na zrobienie tego bez wciągania dużej ilości kodu, oto jest.
Jedna funkcja, która nie jest tak znana, jak
JSON.stringify()
jestconsole.table()
. Po prostu wywołajconsole.table(whatever);
, a zapisze zmienną w konsoli w formacie tabelarycznym, dzięki czemu przeglądanie zawartości zmiennej będzie dość łatwe i wygodne.źródło
znacznie oszczędza i pokazuje, gdzie był obiekt cyklu .
produkuje
źródło
obj.b=this'
gdyby ktoś wiedział, jak zapobiec bardzo długim calcom wykonanym z niewłaściwego podanego zakresu,this
byłoby miło zobaczyć tutajseen.indexOf(v) != -1
Tworzę też projekt na githubie, który może serializować cykliczny obiekt i przywrócić klasę, jeśli zapiszesz ją w atrybucie serializename, takim jak String
https://github.com/bormat/serializeStringifyParseCyclicObject
Edycja: Przekształciłem mój skrypt dla NPM https://github.com/bormat/borto_circular_serialize i zmieniłem nazwy funkcji z francuskiego na angielski.
źródło
Oto przykład struktury danych z cyklicznymi odwołaniami:
Kiedy chcesz ZACHOWAĆ cykliczne odniesienia (przywróć je podczas deserializacji, zamiast „nukingować” je), masz 2 możliwości, które porównam tutaj. Pierwszy to cycle.js Douglasa Crockforda , drugi to mój pakiet syberii . Obie działają najpierw „decyklując” obiekt, tj. Konstruując inny obiekt (bez żadnych cyklicznych odniesień) „zawierający te same informacje”.
Pan Crockford idzie pierwszy:
Jak widać, zagnieżdżona struktura JSON jest zachowywana, ale jest nowa rzecz, czyli obiekty ze specjalną
$ref
właściwością. Zobaczmy, jak to działa.Znak dolara oznacza korzeń.
.bolt
mając$ref
mówi nam, że.bolt
jest to obiekt „już widziany”, a wartość tej specjalnej właściwości (tutaj ciąg $ [„nut”] [„need”]) mówi nam gdzie, patrz===
wyżej. Podobnie dla drugiego$ref
i drugiego===
powyżej.Użyjmy odpowiedniego głębokiego testu równości (mianowicie funkcji Andersa Kaseorga
deepGraphEqual
z zaakceptowanej odpowiedzi na to pytanie ), aby sprawdzić, czy klonowanie działa.Teraz Syberia:
Syberia nie próbuje naśladować „klasycznego” JSON, bez zagnieżdżonej struktury. Graf obiektowy jest opisany w sposób „płaski”. Każdy węzeł wykresu obiektu jest przekształcany w płaskie drzewo (zwykła lista par kluczy-wartość z wartościami całkowitymi), która jest wpisem w
.forest.
indeksie zerowym, znajdujemy obiekt główny, przy wyższych indeksach znajdujemy inne węzły wykres obiektu i wartości ujemne (jakiegoś klucza jakiegoś drzewa w lesie) wskazują naatoms
tablicę (która jest wpisywana poprzez tablicę types, ale pominiemy tutaj szczegóły wpisywania). Wszystkie węzły końcowe znajdują się w tabeli atomów, wszystkie węzły nieterminalne znajdują się w tabeli lasu i od razu można zobaczyć, ile węzłów ma graf obiektu, a mianowicieforest.length
. Sprawdźmy, czy to działa:porównanie
doda sekcję później.
źródło
Brakowało warunku wstępnego, w przeciwnym razie wartości całkowite w obiektach tablic zostaną obcięte, tj. [[08.11.2014 12:30:13, 1095]] 1095 zostanie zmniejszone do 095.
źródło