Ось приклад структури даних з циклічними посиланнями:
function makeToolshed(){
var nut = {name: 'nut'}, bolt = {name: 'bolt'};
nut.needs = bolt; bolt.needs = nut;
return { nut: nut, bolt: bolt };
}
Коли ви хочете зберегти циклічні посилання (відновити їх, коли ви дезаріалізуєте, замість того, щоб "нукірувати" їх), у вас є два варіанти, які я порівняю тут. По- перше це Дугласа Крокфорд в cycle.js , другий мій сибір пакет. Обидва працюють, спочатку "дециркулюючи" об'єкт, тобто будуючи інший об'єкт (без будь-яких циклічних посилань) ", що містить ту саму інформацію".
Містер Крокфорд виходить першим:
JSON.decycle(makeToolshed())
Як бачите, вкладена структура JSON зберігається, але є нова річ - це об'єкти зі спеціальним $ref
властивістю. Подивимося, як це працює.
root = makeToolshed();
[root.bolt === root.nut.needs, root.nut.needs.needs === root.nut]; // retutrns [true,true]
Знак долара означає корінь. .bolt
маючи $ref
говорить нам , що .bolt
це «вже бачив» об'єкт, і значення цього особливого властивості (тут, рядок $ [ «горіх»] [ «потреби»]) говорить нам , де, см перший ===
вище. Так само і для другого, $ref
і для другого ===
вище.
Давайте скористаємося відповідним глибоким тестом на рівність (а саме функцією Андерса Касеорга deepGraphEqual
від прийнятої відповіді на це питання ), щоб перевірити, чи працює клонування.
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
Тепер, Сибір:
JSON.Siberia.forestify(makeToolshed())
Сибір не намагається імітувати "класичний" JSON, немає вкладеної структури. Об'єктний графік описаний "плоско". Кожен вузол об’єктного графіка перетворюється на плоске дерево (список простих значень ключових пар з цілими значеннями), який є записом у .forest.
нулі індексу, ми знаходимо кореневий об'єкт, у більш високих індексах знаходимо інші вузли об’єктний графік та негативні значення (деякого ключа якогось дерева лісу) вказують на atoms
масив (який набирається через масив типів, але ми пропустимо тут деталі введення тексту). Усі кінцеві вузли знаходяться в таблиці атомів, усі нетермінальні вузли - у лісовій таблиці, і ви можете відразу побачити, скільки вузлів має графік об'єкта, а саме forest.length
. Давайте перевіримо, чи працює:
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
порівняння
буде додано розділ пізніше.