[javascript] JS에서 isNaN (null) == false 인 이유는 무엇입니까?

JS 의이 코드는 나에게 “널은 숫자라고 생각한다”라는 팝업을 표시하는데 약간 혼란스러워합니다. 내가 무엇을 놓치고 있습니까?

if (isNaN(null)) {
  alert("null is not a number");
} else {
  alert("i think null is a number");
}

Firefox 3을 사용하고 있습니다. 브라우저 버그입니까?

다른 테스트 :

console.log(null == NaN);   // false
console.log(isNaN("text")); // true
console.log(NaN == "text"); // false

그렇다면 문제는 NaN과 정확히 비교되지 않는 것 같습니다.

편집 : 이제 질문에 대한 답을 얻었습니다. 아카이브에 더 나은 버전을 갖도록 게시물을 정리했습니다. 그러나 이로 인해 일부 의견과 일부 답변도 이해할 수 없습니다. 그들의 저자를 비난하지 마십시오. 내가 바꾼 것들 중 하나는 다음과 같습니다.

  • 헤드 라인의 의미를 되돌려 서 헤드 라인을 망친다는 메모를 제거했습니다.
  • 이전 답변에서는 왜 동작이 이상하다고 생각하는지 명확하게 밝히지 않았으므로 문자열을 확인하고 수동 비교를 수행하는 예제를 추가했습니다.


답변

코드가 ” x숫자입니까?” 의 특정 사례와 함께 x = null. isNaN()이 질문에 답하기 위해 함수를 사용할 수 있지만, 의미 상 구체적으로 value를 참조합니다 NaN. 위키 백과에서 NaN:

NaN이는 ( N은 오티 N의 암갈색) 특히, 부동 소수점 연산에서, 정의되지 않았거나 표현할 수없는 값을 나타내는 수치 데이터 유형의 값이다.

대부분의 경우 “null 숫자입니까?” 아니야. 그러나 isNaN(null) == false의미 상으로는 정확 null하지 않습니다.NaN .

알고리즘 설명은 다음과 같습니다.

이 함수 isNaN(x)는 전달 된 매개 변수를 숫자 1 (과 동일 Number(x)) 로 변환하려고 시도한 다음 값이 0인지 테스트합니다 NaN. 매개 변수를 숫자로 변환 할 수 없으면 2Number(x) 를 리턴 합니다. 따라서 매개 변수 를 숫자로 변환하면 결과 가 true로 반환됩니다. 그렇지 않으면 false를 반환합니다.NaNxNaN

따라서 특정의 경우 x = null, null숫자 0 (평가 시도로 변환되고 Number(null), 그것은 0을 반환 참조) isNaN(0)반환 거짓. 숫자 만있는 문자열은 숫자로 변환 될 수 있으며 isNaN도 false를 반환합니다. 'abcd'숫자로 변환 할 수없는 문자열 (예 isNaN('abcd'):)은 특히 return 때문에 true를 반환 Number('abcd')합니다 NaN.

이러한 명백한 경계 사례 외에도 0/0과 같은 NaN을 반환하는 표준 수치 이유가 있습니다.

질문에 표시된 평등에 대한 일관성이없는 것처럼 보이는 테스트의 경우, 동작 1 은 자신을 포함하여 다른 피연산자에 관계없이 NaN모든 비교 x == NaN가 거짓 이되도록 지정 NaN됩니다 .


답변

방금이 문제에 부딪 쳤습니다.

나에게 isNaN을 사용하는 가장 좋은 방법은

isNaN(parseInt(myInt))

피조 메의 예를 위에서 살펴보면

var x = [undefined, NaN,     'blah', 0/0,  null, 0,     '0',   1,     1/0, -1/0,  Number(5)]
x.map( function(n){ return isNaN(parseInt(n))})
        [true,      true,    true,   true, true, false, false, false, true, true, false]

(입력에 따라 결과를 정렬했기 때문에 더 읽기 쉽기를 바랍니다.)

이것은 나에게 더 좋아 보인다.


답변

(나의 다른 의견은 실용적인 접근 방식을 취합니다. 이론적 인 측면이 있습니다.)

Javascript가 구현하는 ECMA 262 표준을 찾았습니다 . isNan에 대한 사양 :

인수에 ToNumber를 적용한 다음 결과가 NaN이면 true를, 그렇지 않으면 false를 반환합니다.

9.3 절은 ToNumber(호출 가능한 함수가 아니라 타입 변환 시스템의 구성 요소)의 동작을 명시한다 . 표를 요약하면 특정 입력 유형이 NaN을 생성 할 수 있습니다. 이것들은 type undefined, type number(그러나 value 만 NaN), 프리미티브 표현이있는 객체 NaNstring파싱 ​​할 수없는 객체입니다 . 이 잎 undefined, NaN, new Number(NaN), 대부분의 문자열.

NaN전달 될 때 출력으로 생성 되는 모든 입력은에 공급 될 때을 ToNumber생성합니다 . 이후 캔이 성공적으로 숫자로 변환 할, 그것은 생성하지 않습니다 .trueisNaNnulltrue

그리고 그 이유입니다.


답변

이것은 실제로 방해입니다. 다음은 테스트 한 값의 배열입니다.

var x = [undefined, NaN, 'blah', 0/0, null, 0, '0', 1, 1/0, -1/0, Number(5)]

Firebug 콘솔에서 다음을 평가합니다.

,NaN,blah,NaN,,0,0,1,Infinity,-Infinity,5

전화 x.map(isNaN)를 걸 때 (각 값에서 isNaN을 호출하기 위해) 다음을 얻습니다.

true,true,true,true,false,false,false,false,false,false,false

결론적으로, isNaN쓸모없는 것처럼 보입니다! ( 편집 : isNaN이 Number에 대해서만 정의 되어 있음을 제외하고 는 오해의 소지가있는 이름으로 잘 작동합니다.)

덧붙여 말하면, 이러한 값의 유형은 다음과 같습니다.

x.map(function(n){return typeof n})
-> undefined,number,string,number,object,number,string,number,number,number,number


답변

Null은 NaN이 아니며 문자열은 NaN이 아닙니다. isNaN ()은 실제로 NaN 객체가 있는지 테스트합니다.


답변

JS에 관해서는 확실하지 않지만 다른 언어에서도 비슷한 것을 보았습니다. 일반적으로 함수가 null이 NaN과 정확히 같은지 여부를 확인하기 때문입니다 (예 : null === NaN은 false). 다시 말해서 null이 실제로 숫자라고 생각하는 것이 아니라 null이 NaN이 아니라고 생각합니다. 이것은 JS에서 서로 다르게 표현되어 9! == ‘9’와 같은 방식으로 정확하게 동일하지 않기 때문일 수 있습니다.


답변

ES5에서는 isNaN (number)인수가 NaN으로 강제 변환되면 true를 반환하고 그렇지 않으면 false를 반환합니다.

  • 경우 ToNumber (수) NaN의, true를 돌려줍니다.
  • 그렇지 않으면 false를 반환하십시오.

추상 작업 ToNumber 변환 표를 참조하십시오 . 내부적 JS 엔진 평가 그래서 ToNumber(Null)입니다 +0, 다음, 결국 isNaN(null)입니다false