javascript - recorrer - Serializar el objeto que contiene el valor del objeto cíclico
objeto window javascript ejemplos (5)
Tengo un objeto (árbol de análisis sintáctico) que contiene nodos secundarios que son referencias a otros nodos.
Me gustaría serializar este objeto, usando JSON.stringify()
, pero obtengo: TypeError: cyclic object value
debido a los constructos que mencioné.
¿Cómo podría solucionar esto? No me importa si estas referencias a otros nodos están representadas o no en el objeto serializado.
Por otro lado, eliminar estas propiedades del objeto cuando se están creando parece tedioso y no quisiera hacer cambios en el analizador (narciso).
Creé un GitHub Gist que es capaz de detectar estructuras cíclicas y también las descodifica y codifica: https://gist.github.com/Hoff97/9842228
Para transformar simplemente use JSONE.stringify / JSONE.parse. También elimina y codifica funciones. Si desea deshabilitar esto simplemente elimine las líneas 32-48 y 61-85.
var strg = JSONE.stringify(cyclicObject);
var cycObject = JSONE.parse(strg);
Aquí puedes encontrar un violín de ejemplo:
También creo un proyecto github que puede serializar un objeto cíclico y restaurar la clase si lo guarda en el atributo serializename como un 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
Editar: he transformado mi script para NPM https://github.com/bormat/borto_circular_serialize y tengo nombres de funciones de cambio de francés a inglés.
Utilice el segundo parámetro de stringify
, la función de sustitución , para excluir objetos ya serializados:
var seen = [];
JSON.stringify(obj, function(key, val) {
if (val != null && typeof val == "object") {
if (seen.indexOf(val) >= 0) {
return;
}
seen.push(val);
}
return val;
});
Como se señaló correctamente en otros comentarios, este código elimina todos los objetos "vistos", no solo los "recursivos".
Por ejemplo, para:
a = {x:1};
obj = [a, a];
el resultado será incorrecto Si su estructura es así, el decycle de Crockford es una mejor opción.
mucho ahorro y muestra dónde estaba un objeto de ciclo .
<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>
produce
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
}
);
}
Faltaba una condición previa; de lo contrario, los valores enteros en objetos de matriz se truncan, es decir [[08.11.2014 12:30:13, 1095]] 1095 se reduce a 095.