823 votes

JSON.stringify, éviter TypeError : conversion structure circulaire en JSON

J’ai un gros objet que je veux convertir en JSON et l’envoyer. Toutefois, il a structure circulaire. Je veux jeter quelque références circulaires existent et envoyer tout ce qui peut être enchaîné. Comment je fais que ?

Merci.

Je veux stringify obj dans :

840voto

Erel Segal Halevi Points 2308

En Node.js, vous pouvez utiliser util.inspect(object). Il remplace automatiquement les liens circulaire avec « [circulaire] ».

717voto

Rob W Points 125904

Utilisation `` avec un aliment d’allaitement personnalisé. Par exemple :

L’aliment d’allaitement dans cet exemple n’est pas 100 % correct (selon votre définition de « double »). Dans le cas suivant, une valeur est ignorée :

Mais le concept se tient : utiliser un substitut personnalisé et suivre les valeurs de l’objet analysé.

49voto

guy mograbi Points 2418

J’ai vraiment aimé solution de Trindaz - plus prolixe, mais il avait quelques bugs. Je les fixe pour celui qui aime ça aussi.

De plus, j’ai ajouté une limite de longueur sur mes objets du cache.

Si l’objet, que je suis d’impression est vraiment très importante - je veux dire infiniment grand - je veux limiter mon algorithme.

45voto

Nux Points 1053

Notez qu'il existe également un JSON.decycle méthode mise en œuvre par Douglas Crockford. Voir sa cycle.js. Cela vous permet de stringify presque toute structure standard:

var a = [];
a[0] = a;
a[1] = 123;
console.log(JSON.stringify(JSON.decycle(a)));
// result: '[{"$ref":"$"},123]'.

Vous pouvez également recréer objet original retrocycle méthode. Si vous n'avez pas à enlever des cycles à partir d'objets de stringify.

Cependant, cette volonté de ne pas travailler pour les Nœuds DOM (qui sont en cause typique de cycles dans la vie réelle des cas d'utilisation). Par exemple, cela permettra de lancer:

var a = [document.body];
console.log(JSON.stringify(JSON.decycle(a)));

J'ai fait une fourchette de résoudre ce problème (voir mon cycle.js fourche). Cela devrait fonctionner:

var a = [document.body];
console.log(JSON.stringify(JSON.decycle(a, true)));

14voto

Trindaz Points 2353

Pour l'avenir, les googlers la recherche d'une solution à ce problème lorsque vous n'avez pas maintenant les clés de toutes les références circulaires, vous pouvez utiliser un wrapper autour du JSON.stringify fonction d'écarter les références circulaires. Voir un exemple de script à https://gist.github.com/4653128.

La solution se résume essentiellement à garder une référence précédemment imprimés objets dans un tableau, et en vérifiant que dans une fonction replacer avant de retourner une valeur. C'est plus contraignant que de seulement écarter les références circulaires, car il exclut aussi jamais l'impression d'un objet deux fois, l'un des effets secondaires de ce qui est à éviter les références circulaires.

Exemple wrapper:

function stringifyOnce(obj, replacer, indent){
    var printedObjects = [];
    var printedObjectKeys = [];

    function printOnceReplacer(key, value){
        var printedObjIndex = false;
        printedObjects.forEach(function(obj, index){
            if(obj===value){
                printedObjIndex = index;
            }
        });

        if(printedObjIndex && typeof(value)=="object"){
            return "(see " + value.constructor.name.toLowerCase() + " with key " + printedObjectKeys[printedObjIndex] + ")";
        }else{
            var qualifiedKey = key || "(empty key)";
            printedObjects.push(value);
            printedObjectKeys.push(qualifiedKey);
            if(replacer){
                return replacer(key, value);
            }else{
                return value;
            }
        }
    }
    return JSON.stringify(obj, printOnceReplacer, indent);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X