2010-11-26 18 views
18

Así, JSON.stringify proporciona una gran manera de convertir un objeto como JS:¿Cómo se usa JSON.stringify en un método personalizado para JSON?

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

a una cadena JSON como:

{"foo":1} 

Esto lo hace con un segundo argumento opcional que controla qué los campos se deben serializar:

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

Eso es genial, pero hay un problema. Digamos que su "Baz" es en realidad la propiedad de otro objeto, y desea realizar una serie que otro objeto:

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

Bueno, normalmente solo sería definir un método toJSON de Baz, por ejemplo .:

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

Ahora, como he mencionado anteriormente, tenemos la perfecta lógica de "toJSON" Baz ya:

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

pero si intenta poner eso en su toJSON, obtendrá un error de recursividad, porque stringify Wisconsin ll desencadenar la toJSON, lo que dará lugar a la stringify, que se ... :-(

puede solucionar esto con un truco:

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

Pero ... que sólo parece mal. Entonces, mi pregunta es: ¿hay alguna manera de que pueda utilizar el ingenioso poder de serialización incorporado de JSON.stringify dentro de un método toJSON de un objeto (sin tener que ocultar el método toJSON durante la operación de stringify)?

Respuesta

31

Crockford's json2.js dice:

Un método toJSON no serializa: devuelve el valor representado por el par nombre/valor que debe ser serializado, o indefinido si nada debe ser serializado.

Se espera que simplemente devuelva el valor que desea serializar. En su caso, baz.toJSON simplemente debe devolver la parte del objeto que desea baz serializado:

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

Así que si sólo quiero serializar ciertos campos, que tengo que hacer: – machineghost

+0

someObject.baz.toJSON = function () { var ret = {}; para (propiedad de var en esto) { if (! Propiedad en listOfPropertiesToSerialize) continue; ret [propiedad] = esta [propiedad; } return ret; }; – machineghost

+0

No hay forma de simplemente proporcionar la lista de campos y dejar que las cosas integradas de JSON (ya sean de Crockford o del navegador) filtren las cosas, ¿cómo lo hace el método de stringify? – machineghost

Cuestiones relacionadas