Вопрос по jquery, javascript, json – Stringify (преобразовать в JSON) объект JavaScript с циклической ссылкой
Я получил определение объекта JavaScript, которое содержит циклическую ссылку: у него есть свойство, которое ссылается на родительский объект.
Он также имеет функции, которые я не хочу передавать на сервер. Как бы мне сериализовать и десериализовать эти объекты?
Я читал, что лучший способ сделать это - использовать stringify Дугласа Крокфорда. Однако я получаю следующую ошибку в Chrome:
TypeError: Converting circular structure to JSON
Код:
<code>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)); } } </code>
Это тестовый пример, который я создал для этого вопроса. В этом коде есть ошибки, но по существу у меня есть объекты внутри объектов, и ссылка на каждый объект передается, чтобы показать, что является родительским объектом при создании объекта. Каждый объект также содержит функции, которые я не хочу в строковом виде. Я просто хочу свойства, такие какPerson.Name
.
Как мне сериализовать перед отправкой на сервер и десериализовать его, предполагая, что тот же JSON передается обратно?
JS.dropClasses = function(o) {
for (var p in o) {
if (o[p] instanceof jQuery || o[p] instanceof HTMLElement) {
o[p] = null;
}
else if (typeof o[p] == 'object' )
JS.dropClasses(o[p]);
}
};
JSON.stringify(JS.dropClasses(e));
jQuery
Error: User Rate Limit ExceededHTMLElement
Error: User Rate Limit Exceeded
Circular structure ошибка возникает, когда у вас есть свойство объекта, который непосредственно является объектом (a -> a
) или косвенно (a -> b -> a
).
Чтобы избежать сообщения об ошибке, скажите JSON.stringify, что делать, когда встречается циклическая ссылка. Например, если у вас есть человек, указывающий на другого человека («родитель»), который может (или не может) указывать на исходного человека, выполните следующие действия:
JSON.stringify( that.person, function( key, value) {
if( key == 'parent') { return value.id;}
else {return value;}
})
Второй параметр дляstringify
этоfilter function, Здесь он просто преобразует указанный объект в его идентификатор, но вы можете делать все, что захотите, чтобы разорвать циклическую ссылку.
Вы можете проверить приведенный выше код с помощью следующего:
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;
};
});
Кстати, я бы выбрал другое имя атрибута для & quot;parent
& Quot; так как это зарезервированное слово во многих языках (и в DOM). Это может привести к путанице в будущем ...
owner
Error: User Rate Limit Exceededparent
.
parent
Error: User Rate Limit Exceeded
Любой из них должен удовлетворить ваши потребности.
школа дзюдо может представлять циклические ссылки в формате 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"
}
}
Note: You can also de-serialize these circular referenced objects using the dojox.json.ref.fromJson
method.
Другие источники:
Как сериализовать узел DOM в JSON, даже если есть циклические ссылки?
toJson
Error: User Rate Limit ExceededfromJson
Error: User Rate Limit Exceeded
потому что мне нужно было записывать сложные объекты на страницу, поскольку удаленная отладка была невозможна в моей конкретной ситуации. Найден собственный цикл .js Дугласа Крокфорда (инициатор JSON), который аннотирует циклические ссылки в виде строк, так что их можно повторно соединить после анализа. Глубокая копия, очищенная от циклов, безопасна для прохождения через JSON.stringify. Наслаждайтесь!
https://github.com/douglascrockford/JSON-js
cycle.js: This file contains two functions, JSON.decycle and JSON.retrocycle, which make it possible to encode cyclical structures and dags in JSON, and to then recover them. This is a capability that is not provided by ES5. JSONPath is used to represent the links.