Frage

Ich habe ein Objekt (Analysebaum), das untergeordnete Knoten enthält, die auf andere Knoten verweisen.

Ich möchte dieses Objekt mit JSON.stringify() serialisieren, aber ich bekomme

TypeError: zyklischer Objektwert

wegen der Konstrukte, die ich erwähnt habe.

Wie könnte ich das umgehen?Es ist mir egal, ob diese Verweise auf andere Knoten im serialisierten Objekt dargestellt werden oder nicht.

Andererseits scheint es mühsam, diese Eigenschaften beim Erstellen aus dem Objekt zu entfernen, und ich möchte keine Änderungen am Parser (Narzisse) vornehmen.

War es hilfreich?

Lösung

Verwenden Sie den zweiten Parameter von stringify, den Ersetzungsfunktion , um bereits serialisierte Objekte auszuschließen:

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;
});

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

Wie in anderen Kommentaren richtig ausgeführt, entfernt dieser Code jedes "gesehene" Objekt, nicht nur "rekursive".

Zum Beispiel für:

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

Das Ergebnis ist falsch. Wenn Ihre Struktur so ist, möchten Sie möglicherweise Crockfords Decycle oder diese (einfachere) Funktion, die nur rekursive Referenzen durch Nullen ersetzt:

Andere Tipps

Ich habe einen GitHub Gist erstellt, der zyklische Strukturen erkennen und auch de- und codieren kann: https://gist.github.com/Hoff97/9842228

Verwenden Sie zum Transformieren einfach JSONE.stringify / JSONE.parse. Es de- und codiert auch Funktionen.Wenn Sie dies deaktivieren möchten, entfernen Sie einfach die Zeilen 32-48 und 61-85.

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

Ein Beispiel für eine Geige finden Sie hier:

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

viel sparen und es zeigt, wo sich ein Zyklus Objekt befand.

<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>

erzeugt

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
    }
  );
}

Eine Vorbedingung fehlte, andernfalls werden die ganzzahligen Werte in Array-Objekten abgeschnitten, d. h. [[08.11.2014 12:30:13, 1095]] 1095 wird auf 095 reduziert.

Ich erstelle auch ein Github-Projekt, das zyklische Objekte serialisieren und die Klasse wiederherstellen kann, wenn Sie sie wie ein String im Attribut serializename speichern

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

Bearbeiten: Ich habe mein Skript für NPM https://github.com/bormat/borto_circular_serialize geändert und habe Änderungen vorgenommenFunktionsnamen von Französisch bis Englisch.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top