2.8 KiB
Ответ на первый вопрос
Обычный вызов JSON.stringify(team)
выдаст ошибку, так как объекты leader
и soldier
внутри структуры ссылаются друг на друга.
Формат JSON не предусматривает средств для хранения ссылок.
Варианты решения
Чтобы превращать такие структуры в JSON, обычно используются два подхода:
- Добавить в `team` свой код `toJSON`:
team.toJSON = function() { /* свой код, который может создавать копию объекта без круговых ссылок и передавать управление JSON.stringify */ }
При этом, конечно, понадобится и своя функция чтения из JSON, которая будет восстанавливать объект, а затем дополнять его круговыми ссылками.
- Можно учесть возможную проблему в самой структуре, используя вместо ссылок `id`. Как правило, это несложно, ведь на сервере у данных тоже есть идентификаторы.
Изменённая структура может выглядеть так:
var leader = { id: 12, name: "Василий Иванович" }; var soldier = { id: 51, name: "Петька" }; *!* // поменяли прямую ссылку на ID leader.soldierId = 51; soldier.leaderId = 12; */!* var team = { 12: leader, 51: soldier };
..Но действительно ли это решение будет оптимальным? Использовать структуру стало сложнее, и вряд ли это изменение стоит делать лишь из-за JSON. Вот если есть другие преимущества, тогда можно подумать.
Универсальный вариант подхода, описанного выше -- это использование особой реализации JSON, которая не входит в стандарт и поддерживает расширенный формат для поддержки ссылок.
Она, к примеру, есть во фреймворке Dojo.
При вызове dojox.json.ref.toJson(team)
будет создано следующее строковое представление:
//+ no-beautify
[{"name":"Василий Иванович","soldier":{"name":"Петька","leader":{"$ref":"#0"}}},{"$ref":"#0.soldier"}]
Метод разбора такой строки -- также свой: dojox.json.ref.fromJson
.