Stringify (преобразование в JSON) объект JavaScript с круговой ссылкой
у меня есть определение объекта JavaScript, которое содержит циклическую ссылку: у него есть свойство, которое ссылается на родительский объект.
Он также имеет функции, которые я не хочу передавать на сервер. Как бы я сериализовал и десериализовал эти объекты?
Я читал, что лучший способ сделать это-использовать stringify Дугласа Крокфорда. Тем не менее, я получаю следующую ошибку в Chrome:
TypeError: преобразование круговой структура для JSON
код:
function finger(xid, xparent){
this.id = xid;
this.xparent;
//other attributes
}
function arm(xid, xparent){
this.id = xid;
this.parent = xparent;
this.fingers = [];
//other attributes
this.moveArm = function() {
//moveArm function details - not included in this testcase
alert("moveArm Executed");
}
}
function person(xid, xparent, xname){
this.id = xid;
this.parent = xparent;
this.name = xname
this.arms = []
this.createArms = function () {
this.arms[this.arms.length] = new arm(this.id, this);
}
}
function group(xid, xparent){
this.id = xid;
this.parent = xparent;
this.people = [];
that = this;
this.createPerson = function () {
this.people[this.people.length] = new person(this.people.length, this, "someName");
//other commands
}
this.saveGroup = function () {
alert(JSON.stringify(that.people));
}
}
это тестовый случай, который я создал для этого вопроса. В этом коде есть ошибки, но по существу у меня есть объекты внутри объектов и ссылка, передаваемая каждому объекту, чтобы показать, что такое родительский объект при создании объекта. Каждый объект также содержит функции, которые я не хочу строковые. Я просто хочу свойства, такие как Person.Name
.
Как мне сериализовать перед отправкой сервер и десериализовать его, предполагая, что тот же JSON передается обратно?
5 ответов:
кольцевой структуры ошибка возникает, когда у вас есть свойство объекта, сам объект напрямую (
a -> a
) или косвенно (a -> b -> a
).чтобы избежать сообщения об ошибке, сообщите JSON.stringify, что делать, когда он сталкивается с круговой ссылкой. Например, если у вас есть человек, указывающий на другого человека ("родителя"), который может (или не может) указывать на оригинального человека, выполните следующие действия:
JSON.stringify( that.person, function( key, value) { if( key == 'parent') { return value.id;} else {return value;} })
второй параметр
stringify
- это фильтр. Здесь он просто преобразует указанный объект в его идентификатор, но вы можете делать все, что хотите, чтобы разорвать круговую ссылку.вы можете проверить приведенный выше код следующим образом:
function Person( params) { this.id = params['id']; this.name = params['name']; this.father = null; this.fingers = []; // etc. } var me = new Person({ id: 1, name: 'Luke'}); var him = new Person( { id:2, name: 'Darth Vader'}); me.father = him; JSON.stringify(me); // so far so good him.father = me; // time travel assumed :-) JSON.stringify(me); // "TypeError: Converting circular structure to JSON" // But this should do the job: JSON.stringify(me, function( key, value) { if(key == 'father') { return value.id; } else { return value; }; });
кстати, я бы выбрал другое имя атрибута "
parent
" так как это зарезервированное слово во многих языках (и в DOM). Это, как правило, вызывает путаницу в будущем...
получается, что додзе может представлять циклические ссылки в JSON в виде :
{"id":"1","me":{"$ref":"1"}}
вот пример:
require(["dojox/json/ref"], function(){ var me = { name:"Kris", father:{name:"Bill"}, mother:{name:"Karen"} }; me.father.wife = me.mother; var jsonMe = dojox.json.ref.toJson(me); // serialize me alert(jsonMe); });
выдает:
{ "name":"Kris", "father":{ "name":"Bill", "wife":{ "name":"Karen" } }, "mother":{ "$ref":"#father.wife" } }
Примечание: Вы также можете де-сериализовать эти круговые ссылочные объекты с помощью
dojox.json.ref.fromJson
метод.Другие Ресурсы:
как сериализовать узел DOM в JSON, даже если есть циклические ссылки?
Я нашел два подходящих модуля для обработки циклических ссылок в JSON.
- CircularJSON https://github.com/WebReflection/circular-json выход которого можно использовать как входной сигнал к.разбор.)( Он также работает в браузерах и узлах.js Также см.: http://webreflection.blogspot.com.au/2013/03/solving-cycles-recursions-and-circulars.html
- Isaacs json-stringify-safe https://github.com/isaacs/json-stringify-safe который может быть более читаемый, но не может быть использован для .разбор и доступен только для узла.js
любой из них должен удовлетворить ваши потребности.
произошло в этом потоке, потому что мне нужно было регистрировать сложные объекты на странице, так как удаленная отладка была невозможна в моей конкретной ситуации. Нашел собственный цикл Дугласа Крокфорда (inceptor of JSON).js, который аннотирует циклические ссылки как строки, чтобы их можно было повторно подключить после синтаксического анализа. Де-циклически глубокое копирование безопасно пройти через формат JSON.преобразовать в строки. Наслаждайтесь!
https://github.com/douglascrockford/JSON-js
цикл.js: Этот файл содержит две функции, JSON.децикл и формат JSON.ретроцикл, который позволяет кодировать циклические структуры и группы обеспечения доступности баз данных в JSON, а затем восстановить их. Это возможность, что не предусмотрено ES5. JSONPath используется для представления ссылок.