[javascript] JSON은 Infinity와 NaN을 제외했습니다. ECMAScript의 JSON 상태?

JSON이 왜 NaN 및 +/- Infinity를 생략했는지 알고 있습니까? NaN 또는 +/- 무한대 값을 포함하는 경우 직렬화 가능한 객체가 아닌 이상한 상황에 Javascript를 배치합니다.

이것은 돌로 캐스팅 된 것 같습니다 : RFC4627ECMA-262 참조 (마지막 편집시 ECMA-262 pdf 683 페이지 24.5.2, JSON.stringify, 참고 4, 683 페이지 참조) :

유한 번호는을 호출하여 마치 문자열로 표시됩니다 ToString(number). 부호에 관계없이 NaN 및 Infinity는 String으로 표시됩니다 null.



답변

Infinity그리고 NaN하지 키워드 또는 아무것도 특별하다, 그들은 단지 전역 객체의 속성 (있는 그대로이다 undefined)와 같은이 변경 될 수있다. 당신이 경우에 진정한 JSON 문자열이 ECMA 스크립트에서 같은 결과가 있어야 본질적으로 – 그것은 JSON은 사양에 포함하지 않는 이유입니다 eval(jsonString)JSON.parse(jsonString).

그것이 허용되면 누군가가 비슷한 코드를 주입 ​​할 수 있습니다

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

포럼 (또는 무엇이든)으로 연결 한 다음 해당 사이트의 모든 json 사용법이 손상 될 수 있습니다.


답변

원래 질문에 따르면 : 이것은 JSON에서 불행한 누락이라는 점에서 사용자 “cbare”에 동의합니다. IEEE754는이를 부동 소수점 숫자의 세 가지 특수 값으로 정의합니다. 따라서 JSON은 IEEE754 부동 소수점 숫자를 완전히 나타낼 수 없습니다. ECMA262 5.1에 정의 된 JSON은 해당 숫자가 IEEE754를 기반으로하는지 여부를 정의하지 않기 때문에 실제로 더 나쁩니다. ECMA262의 stringify () 함수에 대해 설명 된 설계 흐름은 세 가지 특수 IEEE 값을 언급하므로 실제로 IEEE754 부동 소수점 숫자를 지원하려는 의도 일 수 있습니다.

XML 데이터 유형 xs : float 및 xs : double은 IEEE754 부동 소수점 숫자를 기반으로하며 이러한 세 가지 특수 값의 표현을 지원한다는 질문과 관련이없는 다른 데이터 요소 중 하나입니다 (W3C XSD 1.0 Part 2 참조). , 데이터 유형).


답변

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에서는 그러한 것을 구현하기 위해 직렬화 메소드를 대체 할 수 있다는 것을 알고 있습니다. 직렬화 위치를 잘 모르므로 직렬화 메소드에서 구현하는 방법에 대한 세부 정보를 제공 할 수 없습니다.


답변

“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"}"


답변

직렬화 코드에 액세스 할 수있는 경우 무한대를 1.0e + 1024로 나타낼 수 있습니다. 지수가 너무 커서 이중으로 표현할 수 없으며 역 직렬화 할 때 무한대로 표시됩니다. 웹킷에서 작동하며 다른 json 파서에 대해 확신이 없습니다!


답변

현재 IEEE Std 754-2008에는 두 개의 서로 다른 64 비트 부동 소수점 표현 (십진수 64 비트 부동 소수점 유형 및 이진 64 비트 부동 소수점 유형)에 대한 정의가 포함되어 있습니다.

반올림 후 문자열 .99999990000000006.9999999IEEE 이진 64 비트 표현 과 동일 하지만 IEEE 10 진수 64 비트 표현 과 동일 하지 않습니다.9999999 . 64 비트 IEEE 10 진수 부동 소수점에서는 소수점 값 과 같지 않은 .99999990000000006값으로 반올림 합니다..9999999000000001.9999999

JSON은 숫자 값을 10 진수의 숫자 문자열로 취급하기 때문에 IEEE 2 진 및 10 진 부동 소수점 표현 (예 : IBM Power)을 모두 지원하는 시스템에서 두 가지 IEEE 숫자 부동 소수점 값 중 어느 것이 예정된.


답변

{ “key”: Infinity}와 같은 경우의 잠재적 해결 방법 :

JSON.parse(theString.replace(/":(Infinity|-IsNaN)/g, '":"{{$1}}"'), function(k, v) {
   if (v === '{{Infinity}}') return Infinity;
   else if (v === '{{-Infinity}}') return -Infinity;
   else if (v === '{{NaN}}') return NaN;
   return v;
   });

일반적인 아이디어는 유효하지 않은 값의 발생을 구문 분석 할 때 인식 할 문자열로 바꾸고 적절한 JavaScript 표현으로 다시 바꾸는 것입니다.