Irgendeine Idee, warum JSON NaN und +/- Infinity weggelassen hat? Es versetzt Javascript in die seltsame Situation, in der Objekte, die sonst serialisierbar wären, dies nicht tun, wenn sie NaN- oder +/- unendlich Werte enthalten.
Sieht so aus, als wäre dies in Stein gemeißelt: siehe RFC4627 und ECMA-262 (Abschnitt 24.5.2, JSON.stringify, ANMERKUNG 4, Seite 683 des PDFs ECMA-262 bei der letzten Bearbeitung):
Endliche Zahlen werden wie durch Aufrufen stringifiziert
ToString(number)
. NaN und Infinity werden unabhängig vom Vorzeichen als String dargestelltnull
.
javascript
json
ecma262
Jason S.
quelle
quelle
Antworten:
Infinity
undNaN
sind keine Schlüsselwörter oder etwas Besonderes, sondern nur Eigenschaften des globalen Objekts (wie sie sindundefined
) und können als solche geändert werden. Aus diesem Grund nimmt JSON sie nicht in die Spezifikation auf - im Wesentlichen sollte jede echte JSON-Zeichenfolge in EcmaScript das gleiche Ergebnis haben, wenn Sie dies tuneval(jsonString)
oderJSON.parse(jsonString)
.Wenn es erlaubt wäre, könnte jemand einen ähnlichen Code einfügen
in ein Forum (oder was auch immer) und dann könnte jede json-Nutzung auf dieser Site kompromittiert werden.
quelle
NaN
undInfinity
sind jedoch Eigenschaftsnamen. Während String (1/0) einen String erzeugt"Infinity"
, der nur die String-Darstellung des Werts unendlich ist. Es ist nicht möglich, entwederNaN
oderInfinity
als Literalwert ES darzustellen - Sie müssen entweder einen Ausdruck (z. B. 1/0, 0/0 usw.) oder eine Eigenschaftssuche (bezogen aufInfinity
oderNaN
) verwenden. Da diese eine Codeausführung erfordern, können sie nicht in JSON aufgenommen werden.Zur ursprünglichen Frage: Ich stimme dem Benutzer "cbare" darin zu, dass dies eine unglückliche Auslassung in JSON ist. IEEE754 definiert diese als drei spezielle Werte einer Gleitkommazahl. Daher kann JSON IEEE754-Gleitkommazahlen nicht vollständig darstellen. Es ist sogar noch schlimmer, da JSON im Sinne von ECMA262 5.1 nicht einmal definiert, ob seine Nummern auf IEEE754 basieren. Da der in ECMA262 für die Funktion stringify () beschriebene Entwurfsablauf die drei speziellen IEEE-Werte erwähnt, kann man vermuten, dass tatsächlich die Absicht bestand, IEEE754-Gleitkommazahlen zu unterstützen.
Als ein weiterer Datenpunkt, der nichts mit der Frage zu tun hat: XML-Datentypen xs: float und xs: double geben an, dass sie auf IEEE754-Gleitkommazahlen basieren, und unterstützen die Darstellung dieser drei speziellen Werte (siehe W3C XSD 1.0 Teil 2) , Datentypen).
quelle
Könnten Sie das Nullobjektmuster anpassen und in Ihrem JSON Werte wie darstellen?
Bei der Überprüfung können Sie dann nach dem Typ suchen
Ich weiß, dass Sie in Java Serialisierungsmethoden überschreiben können, um so etwas zu implementieren. Ich bin mir nicht sicher, woher Ihre Serialisierung stammt, daher kann ich keine Details zur Implementierung in die Serialisierungsmethoden angeben.
quelle
undefined
ist kein Schlüsselwort, es ist eine Eigenschaft auf dem globalen Objekt"undefined" in this
im globalen Bereich true zurückgegeben. Es bedeutet auch, dass Sie tun könnenundefined = 42
undif (myVar == undefined)
werden (im Wesentlichen)myVar == 42
. Dies geht auf die Anfänge von Ecmascript nee javascript zurück, in denenundefined
es standardmäßig nicht existierte, also taten esvar undefined
die Leute nur im globalen Bereich. Folglichundefined
konnte kein Schlüsselwort erstellt werden, ohne vorhandene Websites zu beschädigen, und so waren wir für alle Zeiten dazu verdammt, undefiniert eine normale Eigenschaft zu sein.undefined
ist eine globale Eigenschaft, da sie als solche angegeben ist. Konsultieren Sie 15.1.1.3 von ECMAScript-262 3rd ed.Die Zeichenfolgen "Infinity", "-Infinity" und "NaN" entsprechen alle den erwarteten Werten in JS. Ich würde also argumentieren, dass der richtige Weg, diese Werte in JSON darzustellen, in Zeichenfolgen besteht.
Es ist nur eine Schande, dass JSON.stringify dies nicht standardmäßig tut. Aber es gibt einen Weg:
quelle
NaN
undInfinity
hinzugefügt , wie Keyword - Werte wietrue
undfalse
, though.Number("Infinity")
,Number("-Infinity")
undNumber("NaN")
JSON.parse("{ \"value\" : -1e99999 }")
leicht{ value:-Infinity }
in Javascript zurückkehren. Nur ist es einfach nicht kompatibel mit benutzerdefinierten Nummerntypen, die größer sein könntenWenn Sie Zugriff auf den Serialisierungscode haben, können Sie Infinity als 1.0e + 1024 darstellen. Der Exponent ist zu groß, um in einem Doppel dargestellt zu werden, und wenn er deserialisiert ist, wird dies als Unendlichkeit dargestellt. Funktioniert mit Webkit, unsicher über andere JSON-Parser!
quelle
Infinity
wird es immer seinInfinity
, warum also nicht unterstützen?/0
am Ende hinzufügen . Es ist leicht zu analysieren, sofort sichtbar und sogar auswertbar. Es ist unentschuldbar, dass sie es noch nicht zum Standard hinzugefügt haben:{"Not A Number":0/0,"Infinity":1/0,"Negative Infinity":-1/0}
<< Warum nicht?alert(eval("\"Not A Number\"") //works
alert(eval("1/0")) //also works, prints 'Infinity'
. Keine Entschuldigung.Der aktuelle IEEE Std 754-2008 enthält Definitionen für zwei verschiedene 64-Bit-Gleitkommadarstellungen: einen dezimalen 64-Bit-Gleitkommatyp und einen binären 64-Bit-Gleitkommatyp.
Nach dem Runden ist die Zeichenfolge
.99999990000000006
dieselbe wie.9999999
in der binären 64-Bit-Darstellung von IEEE, jedoch NICHT dieselbe wie.9999999
in der 64-Bit-Darstellung mit IEEE-Dezimalzahl. Bei 64-Bit-IEEE-Dezimal-Gleitkomma-.99999990000000006
Runden wird auf den Wert gerundet, der.9999999000000001
nicht mit der Dezimalzahl übereinstimmt.9999999
übereinstimmt.Da JSON numerische Werte nur als numerische Zeichenfolgen mit Dezimalstellen behandelt, kann ein System, das sowohl IEEE-Binär- als auch Dezimal-Gleitkommadarstellungen (wie IBM Power) unterstützt, nicht bestimmen, welcher der beiden möglichen numerischen IEEE-Gleitkommawerte ist beabsichtigt.
quelle
Mögliche Problemumgehung für Fälle wie {"Schlüssel": Unendlichkeit}:
Die allgemeine Idee besteht darin, das Auftreten ungültiger Werte durch eine Zeichenfolge zu ersetzen, die wir beim Parsen erkennen, und diese durch die entsprechende JavaScript-Darstellung zu ersetzen.
quelle
Der Grund ist auf Seite ii im Standard ECMA-404 The JSON Data Interchange Syntax, 1. Ausgabe angegeben
Der Grund liegt nicht, wie viele behauptet haben, in den Darstellungen
NaN
und demInfinity
ECMA-Skript. Einfachheit ist ein zentrales Designprinzip von JSON.quelle
Wenn Sie wie ich keine Kontrolle über den Serialisierungscode haben, können Sie mit NaN-Werten umgehen, indem Sie sie wie folgt durch null oder einen anderen Wert ersetzen:
Im Wesentlichen wird .fail aufgerufen, wenn der ursprüngliche JSON-Parser ein ungültiges Token erkennt. Dann wird ein String-Ersetzen verwendet, um die ungültigen Token zu ersetzen. In meinem Fall ist es eine Ausnahme für den Serialisierer, NaN-Werte zurückzugeben, daher ist diese Methode der beste Ansatz. Wenn die Ergebnisse normalerweise ein ungültiges Token enthalten, ist es besser, nicht $ .get zu verwenden, sondern das JSON-Ergebnis manuell abzurufen und immer die Zeichenfolgenersetzung auszuführen.
quelle
{ "tune": "NaNaNaNaNaNaNaNa BATMAN", "score": NaN }