Tengo un objeto (árbol de análisis) que contiene nodos secundarios que son referencias a otros nodos.
Me gustaría serializar este objeto, usando JSON.stringify()
, pero obtengo
TypeError: valor de objeto cíclico
por las construcciones 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 crean parece tedioso y no quisiera hacer cambios en el analizador (narciso).
javascript
json
jsonserializer
stringify
Loos Duros
fuente
fuente
cycle.js
como respuesta aquí, ya que es la solución más adecuada para muchos casos. Parece apropiado que publiques esa respuesta, ya que eres el primero en hacer referencia a ella (en tu comentario a continuación). Si no tiene ganas de publicarlo como respuesta, eventualmente lo haré.Respuestas:
Use el segundo parámetro de
stringify
, la función de reemplazo , para excluir objetos ya serializados:http://jsfiddle.net/mH6cJ/38/
Como se señaló correctamente en otros comentarios, este código elimina todos los objetos "vistos", no solo los "recursivos".
Por ejemplo, para:
El resultado será incorrecto. Si su estructura es así, es posible que desee utilizar el decícleo de Crockford o esta función (más simple) que simplemente reemplaza las referencias recursivas con nulos:
fuente
Creé un GitHub Gist que es capaz de detectar estructuras cíclicas y también descifrarlas y codificarlas: https://gist.github.com/Hoff97/9842228
Para transformar simplemente use JSONE.stringify / JSONE.parse. También des y codifica funciones. Si desea desactivar esto, simplemente elimine las líneas 32-48 y 61-85.
Puede encontrar un ejemplo de violín aquí:
http://jsfiddle.net/hoff97/7UYd4/
fuente
Esta es una especie de respuesta alternativa, pero dado que muchas personas vendrán aquí para depurar sus objetos circulares y no hay realmente una excelente manera de hacerlo sin extraer un montón de código, aquí va.
Una característica que no es tan conocida como
JSON.stringify()
esconsole.table()
. Simplemente llameconsole.table(whatever);
, y registrará la variable en la consola en formato tabular, por lo que es bastante fácil y conveniente examinar detenidamente el contenido de la variable.fuente
mucho ahorro y muestra dónde estaba un objeto de ciclo .
produce
fuente
obj.b=this'
si alguien sabe cómo evitar cálculos muy largos hechos con un alcance incorrecto dadothis
seen.indexOf(v) != -1
También creo un proyecto github que puede serializar objetos cíclicos y restaurar la clase si lo guarda en el atributo serializename como una Cadena
https://github.com/bormat/serializeStringifyParseCyclicObject
Editar: he transformado mi script para NPM https://github.com/bormat/borto_circular_serialize y he cambiado los nombres de las funciones de francés a inglés.
fuente
Aquí hay un ejemplo de una estructura de datos con referencias cíclicas:
Cuando desee MANTENER las referencias cíclicas (restaurarlas cuando deserialice, en lugar de "destruirlas"), tiene 2 opciones, que compararé aquí. Primero es el ciclo.js de Douglas Crockford , segundo es mi paquete de siberia . Ambos trabajan primero "desciclando" el objeto, es decir, construyendo otro objeto (sin ninguna referencia cíclica) "que contenga la misma información".
Crockford va primero:
Como puede ver, la estructura anidada de JSON se conserva, pero hay una cosa nueva, que son los objetos con la
$ref
propiedad especial . Veamos cómo funciona eso.El signo de dólar representa la raíz.
.bolt
Tener$ref
nos dice que.bolt
es un objeto "ya visto", y el valor de esa propiedad especial (aquí, la cadena $ ["tuerca"] ["necesita"]) nos dice dónde, ver primero===
arriba. Asimismo para el segundo$ref
y el segundo===
arriba.Usemos una prueba de igualdad profunda adecuada (es decir, la
deepGraphEqual
función de Anders Kaseorg de la respuesta aceptada a esta pregunta ) para ver si la clonación funciona.Ahora, siberia:
Siberia no intenta imitar JSON "clásico", no hay estructura anidada. El gráfico del objeto se describe de manera "plana". Cada nodo del gráfico de objeto se convierte en un árbol plano (lista de pares de valores de clave simple con valores enteros), que es una entrada en
.forest.
En el índice cero, encontramos el objeto raíz, en índices más altos, encontramos los otros nodos de el gráfico de objetos y los valores negativos (de alguna clave de algún árbol del bosque) apuntan a laatoms
matriz (que se escribe a través de la matriz de tipos, pero omitiremos los detalles de escritura aquí). Todos los nodos terminales están en la tabla de átomos, todos los nodos no terminales están en la tabla del bosque, y puede ver de inmediato cuántos nodos tiene el gráfico de objeto, a saberforest.length
. Probemos si funciona:comparación
agregará la sección más tarde.
fuente
Faltaba una condición previa; de lo contrario, los valores enteros en los objetos de matriz se truncan, es decir, [[08.11.2014 12:30:13, 1095]] 1095 se reduce a 095.
fuente