2010-11-26 4 views
18

So sieht JSON.stringify eine gute Möglichkeit, ein JS-Objekt zu drehen wie:Wie verwenden Sie JSON.Stringify in einer benutzerdefinierten toJSON-Methode?

var baz = {"foo":1, "bar":someFunction}; 

in einem JSON-String wie:

{"foo":1} 

Es tut dies mit einem optionalen zweiten Argumente, das steuert, welche Felder sollten serialisiert werden:

JSON.stringify(baz, ["foo"]); 

Das ist großartig, aber es gibt ein Problem. Lassen Sie uns sagen, dass Ihre „baz“ ist eigentlich die Eigenschaft eines anderen Objekts, und Sie wollen, dass ein anderes Objekt serialisiert:

someObject.baz = {"foo":1, "bar":someFunction}; 
JSON.stringify(someObject, ["baz"]); 

Nun, normalerweise würde man nur eine toJSON Methode baz definieren, zB .:

someObject.baz = {"foo":1, "bar":someFunction}; 
someObject.baz.toJSON = function() { /* logic to "toJSON" baz*/ } 
JSON.stringify(someObject, ["baz"]); 

Nun, wie ich bereits erwähnt, haben wir die perfekte Logik „toJSON“ baz bereits:

someObject.baz.toJSON = function() { 
    return JSON.stringify(baz, ["foo"]); 
} 

aber wenn Sie versuchen, setzen, dass Ihre toJSON um Sie eine Rekursionsfehlers bekommen, weil stringify wi ll die toJSON auslösen, die die stringify auslösen wird, das wird ... :-(

Sie können mit einem Hack dieses Problem umgehen:

someObject.baz.toJSON = function() { 
    var oldToJON = this.toJSON; 
    this.toJSON = null; 
    var ret = JSON.stringify(baz, ["foo"]); 
    this.toJSON = oldToJON; 
    return ret; 
} 

Aber ... das scheint einfach falsch. Also, meine Frage ist: Gibt es eine Möglichkeit, wie Sie die raffinierte eingebaute Serialisierungskraft von JSON.stringify innerhalb einer toJSON-Methode eines Objekts nutzen können (ohne die toJSON-Methode selbst während der stringify-Operation ausblenden)?

Antwort

31

Crockford's json2.js sagt:

A toJSON Methode serialisiert nicht: sie den Wert mit dem Namen/Wert-Paar repräsentiert zurückgibt, die serialisiert werden soll, oder nicht definiert, wenn nichts serialisiert werden soll.

So wird einfach erwartet, dass Sie den Wert zurückgeben, der serialisiert werden soll. In Ihrem Fall baz.toJSON einfach den Teil des baz Objekt zurückgeben soll, die Sie serialisiert werden soll:

someObject.baz.toJSON = function() { 
    return { foo: this.foo }; 
}; 
+0

Also dann, wenn ich nur bestimmte Felder serialisiert werden will, muss ich tun: – machineghost

+0

someObject.baz.toJSON = function () { var ret = {}; für (Var-Eigenschaft in diesem) { wenn (! -Eigenschaft in listOfPropertiesToSerialize) fortfahren; ret [Eigenschaft] = dies [Eigenschaft; } Rückkehr ret; }; – machineghost

+0

Es gibt keine Möglichkeit, nur die Liste der Felder anzugeben und den eingebauten JSON-Kram (ob es sich um Crockfords oder den Browser handelt) zu filtern, wie die Methode stringify? – machineghost

Verwandte Themen