J'ai un objet (arbre d'analyse) qui contient des nœuds enfants qui sont des références à d'autres nœuds.
Je voudrais sérialiser cet objet, en utilisant JSON.stringify()
, mais j'obtiens
TypeError: valeur de l'objet cyclique
à cause des constructions que j'ai mentionnées.
Comment pourrais-je contourner ce problème? Peu m'importe que ces références à d'autres nœuds soient représentées ou non dans l'objet sérialisé.
D'autre part, supprimer ces propriétés de l'objet lors de leur création semble fastidieux et je ne voudrais pas apporter de modifications à l'analyseur (narcisse).
javascript
json
jsonserializer
stringify
Loic Duros
la source
la source
cycle.js
comme réponse ici, car c'est la solution la plus appropriée dans de nombreux cas. Il vous semble approprié de publier cette réponse, puisque vous êtes le premier à la référencer (dans votre commentaire ci-dessous). Si vous n'avez pas envie de l'afficher vous-même comme réponse, je le ferai éventuellement.Réponses:
Utilisez le deuxième paramètre de
stringify
, la fonction de remplacement , pour exclure les objets déjà sérialisés:http://jsfiddle.net/mH6cJ/38/
Comme indiqué correctement dans d'autres commentaires, ce code supprime tous les objets "vus", pas seulement ceux "récursifs".
Par exemple, pour:
le résultat sera incorrect. Si votre structure est comme ça, vous voudrez peut-être utiliser le decycle de Crockford ou cette fonction (plus simple) qui remplace simplement les références récursives par des valeurs nulles:
la source
J'ai créé un GitHub Gist qui est capable de détecter les structures cycliques et également de les décoder et de les encoder: https://gist.github.com/Hoff97/9842228
Pour transformer, utilisez simplement JSONE.stringify / JSONE.parse. Il dé- et encode également les fonctions. Si vous souhaitez désactiver cela, supprimez simplement les lignes 32-48 et 61-85.
Vous pouvez trouver un exemple de violon ici:
http://jsfiddle.net/hoff97/7UYd4/
la source
C'est une sorte de réponse alternative, mais comme beaucoup de gens viendront ici pour déboguer leurs objets circulaires et qu'il n'y a pas vraiment un excellent moyen de le faire sans extraire un tas de code, voilà.
Une fonctionnalité qui n'est pas aussi connue qu'elle l'
JSON.stringify()
estconsole.table()
. Appelez simplementconsole.table(whatever);
, et il enregistrera la variable dans la console au format tabulaire, ce qui rend assez facile et pratique de parcourir le contenu de la variable.la source
beaucoup plus économique et il montre où se trouvait un objet de cycle .
produit
la source
obj.b=this'
si quelqu'un sait comment empêcher de très longs calculs faits d'une mauvaise portée donnée avec cethis
serait bien de voir iciseen.indexOf(v) != -1
Je crée aussi un projet github qui peut sérialiser l'objet cyclique et restaurer la classe si vous l'enregistrez dans l'attribut serializename comme une chaîne
https://github.com/bormat/serializeStringifyParseCyclicObject
Edit: J'ai transformé mon script pour NPM https://github.com/bormat/borto_circular_serialize et j'ai changé les noms de fonctions du français vers l'anglais.
la source
Voici un exemple de structure de données avec des références cycliques:
Lorsque vous souhaitez GARDER les références cycliques (les restaurer lorsque vous les désérialisez, au lieu de les "nuking"), vous avez 2 choix, que je vais comparer ici. Le premier est cycle.js de Douglas Crockford , le second est mon paquet siberia . Les deux fonctionnent en «décyclant» d'abord l'objet, c'est-à-dire en construisant un autre objet (sans aucune référence cyclique) «contenant les mêmes informations».
M. Crockford commence par:
Comme vous le voyez, la structure imbriquée de JSON est conservée, mais il y a une nouvelle chose, qui est des objets avec la
$ref
propriété spéciale . Voyons comment cela fonctionne.Le signe dollar représente la racine.
.bolt
avoir$ref
nous dit que.bolt
c'est un objet "déjà vu", et la valeur de cette propriété spéciale (ici, la chaîne $ ["nut"] ["needs"]) nous indique où, voir d'abord===
ci-dessus. De même pour le deuxième$ref
et le deuxième===
ci-dessus.Utilisons un test d'égalité profonde approprié (à savoir la
deepGraphEqual
fonction d' Anders Kaseorg issue de la réponse acceptée à cette question ) pour voir si le clonage fonctionne.Maintenant, la Sibérie:
Siberia n'essaye pas d'imiter le JSON "classique", pas de structure imbriquée. Le graphe d'objets est décrit de manière "plate". Chaque nœud du graphe d'objet est transformé en un arbre plat (liste de paires clé / valeur simple avec des valeurs entières uniquement), qui est une entrée dans
.forest.
À l'index zéro, nous trouvons l'objet racine, à des indices plus élevés, nous trouvons les autres nœuds de le graphe d'objet et les valeurs négatives (d'une clé d'un arbre de la forêt) pointent vers leatoms
tableau, (qui est tapé via le tableau des types, mais nous ignorerons les détails de saisie ici). Tous les nœuds terminaux sont dans la table des atomes, tous les nœuds non terminaux sont dans la table de la forêt, et vous pouvez voir immédiatement le nombre de nœuds du graphe d'objets, à savoirforest.length
. Testons si cela fonctionne:Comparaison
ajoutera une section plus tard.
la source
Une condition préalable était manquante, sinon les valeurs entières dans les objets du tableau sont tronquées, c'est-à-dire que [[08.11.2014 12:30:13, 1095]] 1095 est réduit à 095.
la source