JSON은 Infinity와 NaN을 제외했습니다. ECMAScript의 JSON 상태?
JSON이 왜 NaN과 +/- Infinity를 생략했는지 알고 있습니까? NaN 또는 +/- 무한대 값을 포함하는 경우 직렬화 가능한 객체가 아닌 이상한 상황에 Javascript를 배치합니다.
이것은 돌로 캐스팅 된 것 같습니다 : RFC4627 및 ECMA-262 (섹션 24.3.2, JSON.stringify, NOTE 4, 507 페이지 마지막 섹션 참조) :
유한 번호는을 호출하는 것처럼 문자열로 표시됩니다
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
은 .9999999
IEEE 이진 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 표현으로 다시 바꾸는 것입니다.
나와 같이 직렬화 코드를 제어 할 수없는 경우 NaN 값을 다음과 같이 해킹 비트로 null 또는 다른 값으로 대체하여 NaN 값을 처리 할 수 있습니다.
$.get("file.json", theCallback)
.fail(function(data) {
theCallback(JSON.parse(data.responseText.replace(/NaN/g,'null')));
} );
In essence, .fail will get called when the original json parser detects an invalid token. Then a string replace is used to replace the invalid tokens. In my case it is an exception for the serialiser to return NaN values so this method is the best approach. If results normally contain invalid token you would be better off not to use $.get but instead to manually retrieve the JSON result and always run the string replacement.
참고URL : https://stackoverflow.com/questions/1423081/json-left-out-infinity-and-nan-json-status-in-ecmascript
'Programing' 카테고리의 다른 글
텍스트 편집에서 android : ems 속성은 무엇입니까? (0) | 2020.06.06 |
---|---|
정렬 로직을 모델, 뷰 또는 컨트롤러에 배치해야합니까? (0) | 2020.06.06 |
비밀번호 소금에 절인 : 모범 사례? (0) | 2020.06.06 |
IEnumerable을 사용한 중첩 된 수익률 (0) | 2020.06.06 |
파이썬 'for'루프에서 범위 지정 (0) | 2020.06.06 |