У меня есть объект (дерево разбора), который содержит дочерние узлы, которые являются ссылками на другие узлы.
Я хотел бы сериализовать этот объект, используя JSON.stringify()
, но я получаю
TypeError: значение циклического объекта
из-за конструкций, которые я упомянул.
Как я мог обойти это? Мне не важно, представлены ли эти ссылки на другие узлы или нет в сериализованном объекте.
С другой стороны, удаление этих свойств из объекта при их создании кажется утомительным, и я бы не хотел вносить изменения в анализатор (нарцисс).
javascript
json
jsonserializer
stringify
Лоик Дурос
источник
источник
cycle.js
получить ответ от Дугласа Крокфорда , поскольку это наиболее подходящее решение для многих случаев. Представляется целесообразным опубликовать этот ответ, поскольку вы первый, кто на него ссылается (в своем комментарии ниже). Если вы не хотите публиковать это как ответ самостоятельно, я в конечном итоге сделаю это.Ответы:
Используйте второй параметр
stringify
, в функции заменителя , чтобы исключить уже сериализованы объекты:http://jsfiddle.net/mH6cJ/38/
Как правильно указано в других комментариях, этот код удаляет все «видимые» объекты, а не только «рекурсивные».
Например, для:
результат будет неверным. Если ваша структура похожа на эту, вы можете использовать функцию decycle Крокфорда или эту (более простую) функцию, которая просто заменяет рекурсивные ссылки нулями:
источник
Я создал GitHub Gist, который способен обнаруживать циклические структуры, а также де- и кодировать их: https://gist.github.com/Hoff97/9842228
Для преобразования просто используйте JSONE.stringify / JSONE.parse. Он также де- и кодирует функции. Если вы хотите отключить это, просто удалите строки 32-48 и 61-85.
Вы можете найти пример скрипки здесь:
http://jsfiddle.net/hoff97/7UYd4/
источник
Это своего рода альтернативный ответ, но поскольку многие люди будут приходить сюда для отладки своих круговых объектов, и на самом деле не существует отличного способа сделать это, не вставляя кучу кода, здесь идет речь.
Одна особенность, которая не так известна, как
JSON.stringify()
естьconsole.table()
. Просто позвонитеconsole.table(whatever);
, и он зарегистрирует переменную в консоли в табличном формате, что делает его довольно простым и удобным для просмотра содержимого переменной.источник
намного экономит, и это показывает, где был объект цикла .
производит
источник
obj.b=this'
если кто-то знает, как предотвратить очень длинные вызовы, сделанные из неправильной заданной области видимости,this
было бы неплохо увидеть здесьseen.indexOf(v) != -1
Я также создаю проект GitHub, который может сериализовать циклический объект и восстановить класс, если вы сохраните его в атрибуте serializename как String
https://github.com/bormat/serializeStringifyParseCyclicObject
Изменить: я изменил свой сценарий для NPM https://github.com/bormat/borto_circular_serialize, и я изменил имена функций с французского на английский.
источник
Вот пример структуры данных с циклическими ссылками:
Если вы хотите сохранить циклические ссылки (восстановить их при десериализации, вместо того, чтобы «обнулять» их), у вас есть 2 варианта, которые я сравню здесь. Первый - это цикл Дугласа Крокфорда. Второй - моя Сибирь. пакет. Оба работают, сначала «дециклируя» объект, т. Е. Создавая другой объект (без каких-либо циклических ссылок), «содержащий ту же информацию».
Мистер Крокфорд идет первым:
Как видите, вложенная структура JSON сохраняется, но есть новая вещь - объекты со специальным
$ref
свойством. Посмотрим, как это работает.Знак доллара обозначает корень.
.bolt
сказав$ref
нам, что.bolt
это «уже увиденный» объект, а значение этого специального свойства (здесь строка $ ["nut"] ["needs"]) говорит нам где, см. сначала===
выше. Аналогично для второго$ref
и второго===
выше.Давайте используем подходящий тест глубокого равенства (а именно функцию Андерса Касерга
deepGraphEqual
из принятого ответа на этот вопрос ), чтобы проверить, работает ли клонирование.Теперь сибирь
Сибирь не пытается имитировать «классический» JSON, без вложенной структуры. Граф объектов описан «плоско». Каждый узел графа объекта превращается в плоское дерево (список пар значений простых ключей со значениями только для целых чисел), которое является записью в
.forest.
нулевом индексе, мы находим корневой объект, в более высоких индексах мы находим другие узлы граф объекта и отрицательные значения (некоторого ключа некоторого дерева леса) указывают наatoms
массив (который набирается через массив типов, но здесь мы пропустим детали ввода). Все терминальные узлы находятся в таблице атомов, все нетерминальные узлы находятся в таблице леса, и вы можете сразу увидеть, сколько узлов имеет граф объекта, а именноforest.length
. Давайте проверим, работает ли это:сравнение
добавлю раздел позже.
источник
Предварительное условие отсутствовало, в противном случае целочисленные значения в объектах массива усекаются, т.е. [[08.11.2014 12:30:13, 1095]] 1095 уменьшается до 095.
источник