javascript - tojson - json stringify replacer




Zeichne ein JavaScript-Objekt mit Zirkelverweis(konvertiere nach JSON) (4)

Diesem Thread ist aufgefallen, weil ich komplexe Objekte auf einer Seite protokollieren musste, da Remote-Debugging in meiner speziellen Situation nicht möglich war. Gefunden Douglas Crockfords (Inzeptor von JSON) eigene cycle.js, die kreisförmige Referenzen als Strings annotieren, so dass sie nach dem Parsen wieder verbunden werden können. Die decycelte tiefe Kopie kann sicher durch JSON.stringify geleitet werden. Genießen!

https://github.com/douglascrockford/JSON-js

cycle.js: Diese Datei enthält zwei Funktionen, JSON.decycle und JSON.retrocycle, die es ermöglichen, zyklische Strukturen und dags in JSON zu codieren und diese dann wiederherzustellen. Dies ist eine Funktion, die nicht von ES5 bereitgestellt wird. JSONPath wird zur Darstellung der Links verwendet.

Ich habe eine JavaScript-Objektdefinition, die einen Zirkelverweis enthält: Es hat eine Eigenschaft, die auf das Elternobjekt verweist.

Es hat auch Funktionen, die ich nicht an den Server weitergeben möchte. Wie würde ich diese Objekte serialisieren und deserialisieren?

Ich habe gelesen, dass die beste Methode, dies zu tun, Douglas Crockfords stringify ist. In Chrome wird jedoch der folgende Fehler angezeigt:

TypeError: Converting circular structure to JSON

Der Code:

function finger(xid, xparent){
    this.id = xid;
    this.xparent;
    //other attributes
}

function arm(xid, xparent){
    this.id = xid;
    this.parent = xparent;
    this.fingers = [];

    //other attributes

    this.moveArm = function() {
        //moveArm function details - not included in this testcase
        alert("moveArm Executed");
    }
}

 function person(xid, xparent, xname){
    this.id = xid;
    this.parent = xparent;
    this.name = xname
    this.arms = []

    this.createArms = function () {
        this.arms[this.arms.length] = new arm(this.id, this);
    }
}

function group(xid, xparent){
    this.id = xid;
    this.parent = xparent;
    this.people = [];
    that = this;

    this.createPerson = function () {
        this.people[this.people.length] = new person(this.people.length, this, "someName");
        //other commands
    }

    this.saveGroup = function () {
        alert(JSON.stringify(that.people));
    }
}

Dies ist ein Testfall, den ich für diese Frage erstellt habe. Es gibt Fehler in diesem Code, aber im Wesentlichen habe ich Objekte innerhalb von Objekten und eine Referenz, die an jedes Objekt übergeben wird, um zu zeigen, was das übergeordnete Objekt ist, wenn das Objekt erstellt wird. Jedes Objekt enthält auch Funktionen, die nicht mit einem String versehen werden sollen. Ich möchte nur die Eigenschaften wie die Person.Name .

Wie serialisiere ich vor dem Senden an den Server und Deserialisierung unter der Annahme, dass die gleiche JSON zurückgegeben wird?


Es sieht so aus, als ob dojo in JSON zirkuläre Referenzen in folgender Form darstellen kann: {"id":"1","me":{"$ref":"1"}}

Hier ist ein Beispiel:

http://jsfiddle.net/dumeG/

require(["dojox/json/ref"], function(){
    var me = {
        name:"Kris",
        father:{name:"Bill"},
        mother:{name:"Karen"}
    };
    me.father.wife = me.mother;
    var jsonMe = dojox.json.ref.toJson(me); // serialize me
    alert(jsonMe);
});​

Produziert:

{
   "name":"Kris",
   "father":{
     "name":"Bill",
     "wife":{
          "name":"Karen"
      }
   },
   "mother":{
     "$ref":"#father.wife"
   }
}

Hinweis: Sie können diese zirkulär referenzierten Objekte auch mithilfe der Methode dojox.json.ref.fromJson .

Andere Ressourcen:

Wie wird der DOM-Knoten zu JSON serialisiert, auch wenn es Zirkelverweise gibt?

JSON.stringify kann keine Zirkelverweise darstellen


Ich habe zwei geeignete Module gefunden, um zirkuläre Referenzen in JSON zu behandeln.

  1. CircularJSON https://github.com/WebReflection/circular-json dessen Ausgabe als Eingabe für .parse () verwendet werden kann. Es funktioniert auch in Browsers & Node.js Siehe auch: http://webreflection.blogspot.com.au/2013/03/solving-cycles-recursions-and-circulars.html
  2. Isaacs json-stringify-safe https://github.com/isaacs/json-stringify-safe das vielleicht lesbarer ist, aber nicht für .parse verwendet werden kann und nur für Node.js verfügbar ist

Beide sollten Ihren Bedürfnissen entsprechen.


Ein zirkulärer Strukturfehler tritt auf, wenn Sie eine Eigenschaft des Objekts haben, die das Objekt selbst ist ( a -> a ) oder indirekt ( a -> b -> a ).

Um die Fehlermeldung zu vermeiden, teilen Sie JSON.stringify mit, was zu tun ist, wenn es auf einen Zirkelverweis stößt. Wenn beispielsweise eine Person auf eine andere Person ("Eltern") verweist, die auf die ursprüngliche Person verweisen kann (oder auch nicht), führen Sie Folgendes aus:

JSON.stringify( that.person, function( key, value) {
  if( key == 'parent') { return value.id;}
  else {return value;}
})

Der zweite stringify Parameter ist eine Filterfunktion . Hier konvertiert es einfach das referenzierte Objekt in seine ID, aber Sie können das tun, was Sie wollen, um die Zirkelreferenz zu brechen.

Sie können den obigen Code mit folgendem testen:

function Person( params) {
  this.id = params['id'];
  this.name = params['name']; 
  this.father = null;
  this.fingers = [];
  // etc.
}

var me = new Person({ id: 1, name: 'Luke'});
var him = new Person( { id:2, name: 'Darth Vader'});
me.father = him; 
JSON.stringify(me); // so far so good

him.father = me; // time travel assumed :-)
JSON.stringify(me); // "TypeError: Converting circular structure to JSON"
// But this should do the job:
JSON.stringify(me, function( key, value) {
  if(key == 'father') { 
    return value.id;
  } else {
    return value;
  };
});

Übrigens würde ich einen anderen Attributnamen als " parent " wählen, da es in vielen Sprachen (und in DOM) ein reserviertes Wort ist. Dies führt zu Verwirrung auf der Straße ...





stringify