序列化包含循环对象值的对象

我有一个对象(parsing树),其中包含引用其他节点的子节点。

我想序列化这个对象,使用JSON.stringify() ,但我得到: TypeError: cyclic object value因为我提到的构造。

我怎么能解决这个问题? 对于其他节点的这些引用是否在序列化对象中表示或者不在序列化对象中并不重要。

另一方面,从对象中删除这些属性时,他们正在创build似乎乏味,我不想修改parsing器(水仙)。

使用stringify的第二个参数replace器函数来排除已经序列化的对象:

 seen = []; JSON.stringify(obj, function(key, val) { if (val != null && typeof val == "object") { if (seen.indexOf(val) >= 0) { return; } seen.push(val); } return val; }); 

http://jsfiddle.net/mH6cJ/38/

正如在评论中正确指出的那样,这段代码删除了每个“看到”的对象,而不是“recursion的”对象。 例如,为

 a = {x:1}; obj = [a, a]; 

结果将是不正确的。 如果你的结构是这样的,Crockford的回收是一个更好的select。

我创build了一个GitHub Gist,它能够检测循环结构,并对它们进行解码和编码: https : //gist.github.com/Hoff97/9842228

转换只是使用JSONE.stringify / JSONE.parse。 它也解码和编码function。 如果你想禁用这只是删除行32-48和61-85。

 var strg = JSONE.stringify(cyclicObject); var cycObject = JSONE.parse(strg); 

你可以在这里find一个例子:

http://jsfiddle.net/hoff97/7UYd4/

更节省,它显示了一个循环对象的位置。

 <script> var jsonify=function(o){ var seen=[]; var jso=JSON.stringify(o, function(k,v){ if (typeof v =='object') { if ( !seen.indexOf(v) ) { return '__cycle__'; } seen.push(v); } return v; }); return jso; }; var obj={ g:{ d:[2,5], j:2 }, e:10 }; obj.someloopshere = [ obj.g, obj, { a: [ obj.e, obj ] } ]; console.log('jsonify=',jsonify(obj)); </script> 

产生

 jsonify = {"g":{"d":[2,5],"j":2},"e":10,"someloopshere":[{"d":[2,5],"j":2},"__cycle__",{"a":[10,"__cycle__"]}]} 
 function stringifyObject ( obj ) { if ( _.isArray( obj ) || !_.isObject( obj ) ) { return obj.toString() } var seen = []; return JSON.stringify( obj, function( key, val ) { if (val != null && typeof val == "object") { if ( seen.indexOf( val ) >= 0 ) return seen.push( val ) } return val } ); } 

缺less一个先决条件,否则数组对象中的整数值被截断,即[[08.11.2014 12:30:13,1095]] 1095被减less到095。

我创build了一个github项目,可以序列化循环对象和恢复类,如果你保存在serializename属性像一个string

 var d={} var a = {b:25,c:6,enfant:d}; d.papa=a; var b = serializeObjet(a); assert.equal( b, "{0:{b:25,c:6,enfant:'tab[1]'},1:{papa:'tab[0]'}}" ); var retCaseDep = parseChaine(b) assert.equal( retCaseDep.b, 25 ); assert.equal( retCaseDep.enfant.papa, retCaseDep ); 

https://github.com/bormat/serializeStringifyParseCyclicObject

编辑:我已经改变我的脚本为NPM https://github.com/bormat/borto_circular_serialize ,我已经从法语到英语更改函数名称。