web-dev-qa-db-ja.com

JSONはInfinityとNaNを除外しました。 ECMAScriptのJSONステータス?

JSONがNaNと+/- Infinityを除外した理由は何ですか?オブジェクトがNaNまたは+/-無限大の値を含んでいる場合、そうでなければシリアル化できるオブジェクトがそうでないという奇妙な状況にJavascriptを置きます。

このように見えます: RFC4627 および ECMA-262 を参照してください(セクション24.3.2、JSON.stringify、注4、最後の編集で507ページ):

有限数は、ToString(number)を呼び出すことによって文字列化されます。 NaNおよび符号に関係なくInfinityは、String nullとして表されます。

155
Jason S

InfinityNaNはキーワードや特別なものではなく、グローバルオブジェクトのプロパティ(undefinedと同様)であり、変更可能です。そのため、JSONは仕様にそれらを含めません。本質的に、eval(jsonString)またはJSON.parse(jsonString)を実行した場合、EcmaScriptで実際のJSON文字列は同じ結果になるはずです。

それが許可された場合、誰かが同じようなコードを注入する可能性があります

NaN={valueOf:function(){ do evil }};
Infinity={valueOf:function(){ do evil }};

フォーラム(またはその他)にアクセスすると、そのサイトでのjsonの使用が危険にさらされる可能性があります。

84
olliej

元の質問について:これはJSONの不幸な省略であるという点でユーザー「cbare」に同意します。 IEEE754では、これらを浮動小数点数の3つの特別な値として定義しています。そのため、JSONはIEEE754浮動小数点数を完全には表現できません。実際、ECMA262 5.1で定義されているJSONは、その番号がIEEE754に基づいているかどうかも定義していないため、さらに悪化します。 ECMA262のstringify()関数について説明されている設計フローでは、3つの特別なIEEE値に言及しているため、IEEE754浮動小数点数をサポートする意図が実際にあったと推測できます。

他のデータポイントとして、質問とは無関係:XMLデータ型xs:floatおよびxs:doubleは、それらがIEEE754浮動小数点数に基づいていることを示し、これらの3つの特別な値の表現をサポートします(W3C XSD 1.0パート2を参照) 、データ型)。

52
Andreas Maier

Nullオブジェクトパターンを適応させて、JSONで次のような値を表現できますか

"myNum" : {
   "isNaN" :false,
   "isInfinity" :true
}

その後、チェックするときに、タイプを確認できます

if (typeof(myObj.myNum) == 'number') {/* do this */}
else if (myObj.myNum.isNaN) {/* do that*/}
else if (myObj.myNum.isInfinity) {/* Do another thing */}

私はJavaでそのようなことを実装するためにシリアル化メソッドをオーバーライドできることを知っています。どこからシリアル化するのかわからないので、シリアル化メソッドで実装する方法の詳細を説明できません。

15
Zoidberg

文字列「Infinity」、「-Infinity」、および「NaN」はすべて、JSの期待値に強制されます。したがって、JSONでこれらの値を表す正しい方法は文字列であると主張します。

> +"Infinity"
Infinity

> +"-Infinity"
-Infinity

> +"NaN"
NaN

JSON.stringifyはデフォルトではこれを行いません。しかし、方法があります:

> JSON.stringify({ x: Infinity }, function (k,v) { return v === Infinity ? "Infinity" : v; })
"{"x":"Infinity"}"
10
teh_senaus

シリアル化コードにアクセスできる場合、Infinityを1.0e + 1024として表すことができます。指数は大きすぎてdoubleで表すことができず、デシリアライズされるとこれはInfinityとして表されます。 Webkitで動作し、他のJSONパーサーについては不明です!

6
kuwerty

現在のIEEE Std 754-2008には、10進数の64ビット浮動小数点型とバイナリの64ビット浮動小数点型の2つの異なる64ビット浮動小数点表現の定義が含まれています。

文字列を丸めた後、.99999990000000006はIEEEバイナリ64ビット表現の.9999999と同じですが、[〜#〜] not [〜#〜]と同じです.9999999 IEEE 10進64ビット表現。 64ビットIEEE 10進浮動小数点では、.99999990000000006は10進.9999999000000001値とは異なる値.9999999に丸められます。

JSONは単に数値を10進数の数値文字列として扱うため、IEEE 2進数と10進数の両方の浮動小数点表現(IBM Powerなど)をサポートするシステムが、2つの可能なIEEE数値浮動小数点値のどちらを使用するかを決定する方法はありません意図されました。

1
Steven Hobbs