Oto przykład struktury danych z cyklicznymi odwołaniami:
function makeToolshed(){
var nut = {name: 'nut'}, bolt = {name: 'bolt'};
nut.needs = bolt; bolt.needs = nut;
return { nut: nut, bolt: bolt };
}
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:
JSON.decycle(makeToolshed())
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.
root = makeToolshed();
[root.bolt === root.nut.needs, root.nut.needs.needs === root.nut]; // retutrns [true,true]
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.
root = makeToolshed();
clone = JSON.retrocycle(JSON.decycle(root));
deepGraphEqual(root, clone) // true
serialized = JSON.stringify(JSON.decycle(root));
clone2 = JSON.retrocycle(JSON.parse(serialized));
deepGraphEqual(root, clone2); // true
Teraz Syberia:
JSON.Siberia.forestify(makeToolshed())
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ą na atoms
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 mianowicie forest.length
. Sprawdźmy, czy to działa:
root = makeToolshed();
clone = JSON.Siberia.unforestify(JSON.Siberia.forestify(root));
deepGraphEqual(root, clone); // true
serialized = JSON.Siberia.stringify(JSON.Siberia.forestify(root));
clone2 = JSON.Siberia.unforestify(JSON.Siberia.unstringify(serialized));
deepGraphEqual(root, clone2); // true
porównanie
doda sekcję później.