90 votes

JSON.stringify () bizarreness

Je suis à essayer de comprendre ce qui va mal avec mon sérialisation json, disposer de la version actuelle de mon application avec et ancien et suis trouver surprenantes différences dans la façon de JSON.stringify() fonctionne (en Utilisant la librairie JSON à partir de json.org).

Dans l'ancienne version de mon application:

 JSON.stringify({"a":[1,2]})

donne-moi cela;

"{\"a\":[1,2]}"

dans la nouvelle version,

 JSON.stringify({"a":[1,2]})

donne-moi cela;

"{\"a\":\"[1, 2]\"}"

toute idée de ce qui pourrait avoir changé à faire la même bibliothèque de mettre des guillemets autour du tableau entre crochets dans la nouvelle version?

83voto

Raphael Schweikert Points 6380

Étant donné que JSON.stringify est livré avec certains navigateurs récemment, je suggérerais de l’utiliser au lieu de toJSON de Prototype. Vous devriez alors vérifier window.JSON && window.JSON.stringify et inclure uniquement la bibliothèque json.org sinon (via document.createElement('script') …). Pour résoudre les incompatibilités, utilisez:

 if(window.Prototype) {
    delete Object.prototype.toJSON;
    delete Array.prototype.toJSON;
    delete Hash.prototype.toJSON;
    delete String.prototype.toJSON;
}
 

82voto

Jean Vincent Points 3136

La fonction JSON.stringify() définie dans ECMAScript 5 et au-dessus (Page 201 - l'Objet JSON, pseudo-code de la Page 205), utilise la fonction de la méthode toJSON() lorsque disponibles sur les objets.

Parce que Prototype.js (ou d'une autre bibliothèque que vous utilisez) définit un Tableau.le prototype.la méthode toJSON() de la fonction, les tableaux sont d'abord converties en chaînes de caractères à l'aide du Tableau.le prototype.la méthode toJSON (), puis de la chaîne cité par JSON.stringify(), d'où la mauvaise supplémentaire des guillemets autour de la tableaux.

La solution est donc simple et trivial (c'est une version simplifiée de Raphaël Schweikert de la réponse):

delete Array.prototype.toJSON

Ce produit bien sûr des effets secondaires sur les bibliothèques qui s'appuient sur une méthode toJSON() de la fonction à la propriété pour les tableaux. Mais je trouve que c'est un inconvénient mineur compte tenu de l'incompatibilité avec ECMAScript 5.

Il doit être noté que l'Objet JSON définies dans ECMAScript 5 est efficacement mis en œuvre dans les navigateurs modernes et, par conséquent, la meilleure solution est de se conformer à la norme et à modifier les bibliothèques existantes.

16voto

akkishore Points 326

Une solution qui n'affectera pas les autres dépendances Prototype serait:

 var _json_stringify = JSON.stringify;
JSON.stringify = function(value) {
    var _array_tojson = Array.prototype.toJSON;
    delete Array.prototype.toJSON;
    var r=_json_stringify(value);
    Array.prototype.toJSON = _array_tojson;
    return r;
};
 

Cela évite l'incompatibilité Array toJSON avec JSON.stringify et conserve également la fonctionnalité toJSON car d'autres bibliothèques de prototypes peuvent en dépendre.

9voto

Bob Points 4773

Modifier pour le rendre un peu plus précis:

Le problème clé de bits de code est dans le JSON de la bibliothèque de JSON.org (et d'autres implémentations de ECMAScript 5 de l'objet JSON):

 si (valeur && typeof === 'object' &&
 typeof valeur.la méthode toJSON = = = "function") {
 valeur = valeur.la méthode toJSON(clé);
 }

Le problème est que le Prototype de la bibliothèque s'étend Tableau d'inclure une méthode toJSON, dont l'objet JSON va appeler dans le code ci-dessus. Lorsque l'objet JSON frappe le tableau de la valeur, il appelle la méthode toJSON sur le tableau qui est défini à l'état de Prototype, et cette méthode renvoie une chaîne de version de la matrice. Par conséquent, les guillemets autour du tableau entre crochets.

Si vous supprimez la méthode toJSON de l'objet de Tableau de la librairie JSON devrait fonctionner correctement. Ou, il suffit d'utiliser la librairie JSON.

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