Une idée pourquoi JSON a omis NaN et +/- Infinity? Cela met Javascript dans la situation étrange où les objets qui seraient autrement sérialisables, ne le sont pas, s'ils contiennent des valeurs NaN ou +/- infini.
On dirait que cela a été coulé dans la pierre: voir RFC4627 et ECMA-262 (section 24.5.2, JSON.stringify, NOTE 4, page 683 du pdf ECMA-262 lors de la dernière édition):
Les nombres finis sont stringifiés comme en appelant
ToString(number)
. NaN et Infinity, quel que soit le signe, sont représentés par la chaînenull
.
javascript
json
ecma262
Jason S
la source
la source
Réponses:
Infinity
etNaN
ne sont pas des mots clés ou quoi que ce soit de spécial, ce ne sont que des propriétés sur l'objet global (tel quelundefined
) et peuvent donc être modifiées. C'est pour cette raison que JSON ne les inclut pas dans la spécification - en substance, toute vraie chaîne JSON devrait avoir le même résultat dans EcmaScript si vous le faiteseval(jsonString)
ouJSON.parse(jsonString)
.Si cela était autorisé, quelqu'un pourrait injecter du code semblable à
dans un forum (ou autre) et toute utilisation de json sur ce site pourrait être compromise.
la source
NaN
etInfinity
sont des noms de propriétés, alors que String (1/0) produit une chaîne"Infinity"
qui n'est que la représentation sous forme de chaîne de la valeur infinity. Il n'est pas possible de représenter l'unNaN
ou l' autre ouInfinity
comme valeurs littérales est ES - vous devez soit utiliser une expression (par exemple 1/0, 0/0, etc.) ou une recherche de propriété (faisant référence àInfinity
ouNaN
). Comme ceux-ci nécessitent l'exécution de code, ils ne peuvent pas être inclus dans JSON.Sur la question d'origine: je suis d'accord avec l'utilisateur "cbare" en ce sens qu'il s'agit d'une omission malheureuse dans JSON. IEEE754 les définit comme trois valeurs spéciales d'un nombre à virgule flottante. Ainsi, JSON ne peut pas représenter entièrement les nombres à virgule flottante IEEE754. C'est en fait encore pire, puisque JSON tel que défini dans ECMA262 5.1 ne définit même pas si ses nombres sont basés sur IEEE754. Puisque le flux de conception décrit pour la fonction stringify () dans ECMA262 mentionne les trois valeurs spéciales IEEE, on peut soupçonner que l'intention était en fait de prendre en charge les nombres à virgule flottante IEEE754.
Comme un autre point de données, sans rapport avec la question: les types de données XML xs: float et xs: double indiquent qu'ils sont basés sur des nombres à virgule flottante IEEE754, et qu'ils prennent en charge la représentation de ces trois valeurs spéciales (voir W3C XSD 1.0 Partie 2 , Types de données).
la source
Pourriez-vous adapter le modèle d'objet nul et représenter dans votre JSON des valeurs telles que
Ensuite, lors de la vérification, vous pouvez vérifier le type
Je sais qu'en Java, vous pouvez remplacer les méthodes de sérialisation afin de mettre en œuvre une telle chose. Je ne sais pas d'où vient votre sérialisation, donc je ne peux pas donner de détails sur la façon de l'implémenter dans les méthodes de sérialisation.
la source
undefined
n'est pas un mot-clé, c'est une propriété sur l'objet global"undefined" in this
renvoie true dans la portée globale. Cela signifie également que vous pouvez faireundefined = 42
etif (myVar == undefined)
devenir (essentiellement)myVar == 42
. Cela nous ramène aux débuts du javascript ecmascript nee où ilundefined
n'existait pas par défaut, donc les gens l'ont faitvar undefined
dans le monde entier. Par conséquent,undefined
on ne pouvait pas faire un mot-clé sans casser des sites existants, et nous étions donc condamnés à tout jamais à avoir indéfini une propriété normale.undefined
est une propriété globale car elle est spécifiée comme telle. Consultez 15.1.1.3 de ECMAScript-262 3e éd.Les chaînes "Infinity", "-Infinity" et "NaN" contraignent toutes les valeurs attendues dans JS. Je dirais donc que la bonne façon de représenter ces valeurs dans JSON est sous forme de chaînes.
C'est juste dommage que JSON.stringify ne le fasse pas par défaut. Mais il y a un moyen:
la source
NaN
etInfinity
ajouté des valeurs de mot clé commetrue
etfalse
, cependant.Number("Infinity")
,Number("-Infinity")
etNumber("NaN")
JSON.parse("{ \"value\" : -1e99999 }")
retournez facilement{ value:-Infinity }
en javascript. Seulement, il n'est tout simplement pas compatible avec le type de numéro personnalisé qui pourrait être plus grand que celaSi vous avez accès au code de sérialisation, vous pouvez représenter Infinity comme 1.0e + 1024. L'exposant est trop grand pour être représenté dans un double et lorsqu'il est désérialisé, il est représenté par Infinity. Fonctionne sur webkit, pas sûr des autres analyseurs json!
la source
Infinity
sera toujoursInfinity
, alors pourquoi ne pas soutenir cela?/0
à la fin. Il est facilement analysable, immédiatement visible et même évaluable. Il est inexcusable qu'ils ne l'aient pas encore ajouté à la norme:{"Not A Number":0/0,"Infinity":1/0,"Negative Infinity":-1/0}
<< Pourquoi pas?alert(eval("\"Not A Number\"") //works
alert(eval("1/0")) //also works, prints 'Infinity'
. Pas d'excuses.La norme IEEE Std 754-2008 actuelle inclut des définitions pour deux représentations à virgule flottante 64 bits différentes: un type à virgule flottante décimal 64 bits et un type à virgule flottante 64 bits binaire.
Après avoir arrondi, la chaîne
.99999990000000006
est la même que.9999999
dans la représentation binaire 64 bits IEEE, mais ce n'est PAS la même que.9999999
dans la représentation décimale 64 bits IEEE. Dans les arrondis à virgule flottante décimale IEEE 64 bits.99999990000000006
à la valeur.9999999000000001
qui n'est pas la même que la.9999999
valeur décimale .Étant donné que JSON ne traite que les valeurs numériques comme des chaînes numériques de chiffres décimaux, il n'y a aucun moyen pour un système qui prend en charge les représentations à virgule flottante binaire et décimale IEEE (comme IBM Power) de déterminer laquelle des deux valeurs numériques à virgule flottante IEEE possibles est prévu.
la source
Solution de contournement potentielle pour des cas tels que {"key": Infinity}:
L'idée générale est de remplacer les occurrences de valeurs invalides par une chaîne que nous reconnaîtrons lors de l'analyse et de la remplacer par la représentation JavaScript appropriée.
la source
La raison est indiquée à la page ii de la norme ECMA-404 La syntaxe d'échange de données JSON, 1ère édition
La raison n'est pas, comme beaucoup l'ont prétendu, due aux représentations
NaN
et auInfinity
script ECMA. La simplicité est un principe de conception de base de JSON.la source
Si comme moi vous n'avez aucun contrôle sur le code de sérialisation, vous pouvez traiter les valeurs NaN en les remplaçant par null ou toute autre valeur comme un petit hack comme suit:
En substance, .fail sera appelé lorsque l'analyseur json d'origine détecte un jeton invalide. Ensuite, une chaîne de remplacement est utilisée pour remplacer les jetons non valides. Dans mon cas, c'est une exception pour le sérialiseur de renvoyer des valeurs NaN, donc cette méthode est la meilleure approche. Si les résultats contiennent normalement un jeton non valide, vous feriez mieux de ne pas utiliser $ .get mais plutôt de récupérer manuellement le résultat JSON et d'exécuter toujours le remplacement de chaîne.
la source
{ "tune": "NaNaNaNaNaNaNaNa BATMAN", "score": NaN }