Ich versuche herauszufinden, was mit meiner JSON-Serialisierung schief gelaufen ist, habe die aktuelle Version meiner App mit und die alte und finde einige überraschende Unterschiede in der Funktionsweise von JSON.stringify () (mithilfe der JSON-Bibliothek von json.org) ).
In der alten Version meiner App:
JSON.stringify({"a":[1,2]})
gibt mir das;
"{\"a\":[1,2]}"
in der neuen Version,
JSON.stringify({"a":[1,2]})
gibt mir das;
"{\"a\":\"[1, 2]\"}"
Haben Sie eine Idee, was sich geändert haben könnte, damit dieselbe Bibliothek in der neuen Version Anführungszeichen um die Array-Klammern setzt?
javascript
json
prototypejs
Morgancodes
quelle
quelle
Antworten:
Da JSON.stringify in letzter Zeit mit einigen Browsern ausgeliefert wurde, würde ich empfehlen, es anstelle von Prototyps toJSON zu verwenden. Sie würden dann nach window.JSON && window.JSON.stringify suchen und ansonsten nur die json.org-Bibliothek einschließen (via
document.createElement('script')
…). Verwenden Sie zum Beheben der Inkompatibilitäten:quelle
Die in ECMAScript 5 und höher definierte Funktion JSON.stringify () (Seite 201 - das JSON-Objekt, Pseudocode Seite 205) verwendet die Funktion toJSON (), wenn sie für Objekte verfügbar ist.
Da Prototype.js (oder eine andere Bibliothek, die Sie verwenden) eine Array.prototype.toJSON () -Funktion definiert, werden Arrays zuerst mit Array.prototype.toJSON () in Zeichenfolgen konvertiert und dann mit JSON.stringify () als Zeichenfolge angegeben falsche zusätzliche Anführungszeichen um die Arrays.
Die Lösung ist daher einfach und trivial (dies ist eine vereinfachte Version der Antwort von Raphael Schweikert):
Dies führt natürlich zu Nebenwirkungen bei Bibliotheken, die für Arrays auf einer toJSON () - Funktionseigenschaft beruhen. Angesichts der Inkompatibilität mit ECMAScript 5 finde ich dies jedoch eine kleine Unannehmlichkeit.
Es ist zu beachten, dass das in ECMAScript 5 definierte JSON-Objekt in modernen Browsern effizient implementiert wird. Daher besteht die beste Lösung darin, dem Standard zu entsprechen und vorhandene Bibliotheken zu ändern.
quelle
Eine mögliche Lösung, die andere Prototypabhängigkeiten nicht beeinflusst, wäre:
Dies behebt die Inkompatibilität von Array zu JSON mit JSON.stringify und behält auch die JSON-Funktionalität bei, da andere Prototype-Bibliotheken davon abhängen können.
quelle
if(typeof Prototype !== 'undefined' && parseFloat(Prototype.Version.substr(0,3)) < 1.7 && typeof Array.prototype.toJSON !== 'undefined')
. Es funktionierte.Bearbeiten, um etwas genauer zu machen:
Das Problemschlüsselbit des Codes befindet sich in der JSON-Bibliothek von JSON.org (und anderen Implementierungen des JSON-Objekts von ECMAScript 5):
Das Problem ist, dass die Prototype-Bibliothek Array um eine toJSON-Methode erweitert, die das JSON-Objekt im obigen Code aufruft. Wenn das JSON-Objekt den Array-Wert erreicht, ruft es JSON für das in Prototype definierte Array auf, und diese Methode gibt eine Zeichenfolgenversion des Arrays zurück. Daher die Anführungszeichen um die Array-Klammern.
Wenn Sie toJSON aus dem Array-Objekt löschen, sollte die JSON-Bibliothek ordnungsgemäß funktionieren. Oder verwenden Sie einfach die JSON-Bibliothek.
quelle
Ich denke, eine bessere Lösung wäre, dies direkt nach dem Laden des Prototyps aufzunehmen
Dadurch wird die Prototypfunktion als Standard-JSON.stringify () und JSON.parse () verfügbar, die native JSON.parse () bleibt jedoch erhalten, sofern verfügbar, sodass die Kompatibilität mit älteren Browsern verbessert wird.
quelle
Ich spreche nicht so fließend mit Prototype, aber ich habe dies in den Dokumenten gesehen :
Ich bin mir nicht sicher, ob dies das gleiche Problem haben würde, das die aktuelle Codierung hat.
Es gibt auch ein längeres Tutorial zur Verwendung von JSON mit Prototype.
quelle
Dies ist der Code, den ich für dasselbe Problem verwendet habe:
Sie überprüfen, ob Prototyp vorhanden ist, und überprüfen dann die Version. Wenn die alte Version Object.toJSON verwendet (falls definiert), greifen Sie in allen anderen Fällen auf JSON.stringify () zurück.
quelle
So gehe ich damit um.
quelle
Meine tolerante Lösung prüft, ob Array.prototype.toJSON für JSON stringify schädlich ist, und behält es bei, wenn möglich, den umgebenden Code wie erwartet funktionieren zu lassen:
quelle
Wie bereits erwähnt, liegt dies an Prototype.js - speziell an Versionen vor 1.7. Ich hatte eine ähnliche Situation, musste aber Code haben, der funktionierte, ob Prototype.js da war oder nicht; Dies bedeutet, dass ich die Datei Array.prototype.toJSON nicht einfach löschen kann, da ich nicht sicher bin, was davon abhängt. Für diese Situation ist dies die beste Lösung, die ich gefunden habe:
Hoffentlich hilft es jemandem.
quelle
Wenn Sie nicht alles töten möchten und einen Code haben, der in den meisten Browsern in Ordnung ist, können Sie dies folgendermaßen tun:
Dies scheint komplex zu sein, ist jedoch nur für die meisten Anwendungsfälle komplex. Die Hauptidee besteht
JSON.stringify
darin,toJSON
das als Argument übergebene Objekt zu entfernen , dann das alte aufzurufenJSON.stringify
und es schließlich wiederherzustellen.quelle