NaN은 말 그대로 '숫자 아님'이다. 하지만 사실 '유효하지 않은 숫자'라고 하는게 더 적절하다.
var a = 2 / "foo"; // NaN
typeof a === "number"; // true
Not a Number 즉, 숫자가 아닌데 타입이 "number"라니 이 무슨 해괴한 말인가?
var a = 2 / "foo";
a == NaN; // false
a === NaN; // false
NaN === NaN; // false
NaN은 유일하게 자기 자신과 비교를 해도 동등하지 않다.
그래서 NaN을 판별할 수 있는 전역 유틸리티가 있는데 window.isNaN() 이다.
그런데 문제는 말 그대로 '숫자가 아닌지' 만 판단한다.
var a = 2 / "foo";
var b = "foo";
a; // NaN
b; // "foo"
window.isNaN( a ); // true
window.isNaN( b ); // true - ???
b는 숫자가 아니더라도 NaN은 아닌데 이렇게 되면 제대로 된 NaN을 판별할 수가 없다.
ES6부터는 Number.isNaN() 이 생겼다.
ES6이하 브라우저에서는 폴리필을 사용하면 된다.
if (!Number.isNaN) {
Number.isNaN = function (n) {
return (
typeof n === "number" &&
window.isNaN( n )
);
}
}
var a = 2 / "foo";
var b = "foo";
Number.isNaN( a ); // true
Number.isNaN( b ); // false
자기 자신과 비교시 유일하게 다른 값이기 때문에 더 간단히 폴리필을 만들 수도 있다.
if (!Number.isNaN) {
Number.isNaN = function (n) {
return n !== n;
};
}
자바스크립트에서 무한대를 나타내는 값은 양의 무한대 Infinity와 음의 무한대 -Infinity가 있다.
var a = 1 / 0; // Infinity
var b = -1 / 0; // -Infinity
Number.POSITIVE_INFINITY === Infinity; // true
Number.NEGATIVE_INFINITY === -Infinity; // true
Infinity / Infinity; // NaN
무한대를 무한대로 나누면 1이라고 생각할 수 있지만, '무한대' 라는 말 자체가 그 값을 알 수 없이 큰 값이라는 뜻이기 때문에,
무슨 수에서 얼만큼 나눌지 알아야 정확히 똑같이 나눌거 아닌가?
그래서 1이 아닌 NaN(Not a Number가 아닌 유효하지 않은 숫자로 생각하자..)이 반환된다.
아무 양수를 무한대로 나누면? 0
아무 음수를 무한대로 나누면? 0일까?
10 / Infinity; 0
-10 / Infinity; -0
-0 이란 숫자가 나온다.
혼란스럽다. 0은 알겠는데 -0은 대체 왜 존재하는 것인가?
var a = 0 / -3; // -0
var b = 0 * -3; // -0
덧셈과 뺄셈에서는 -0이 나올일이 없다.
IE는 버전에 상관없이 0 이 나온다..;
문자열 / 숫자화 시킬 때 주의
-0을 문자열화 시키면 0이 된다.
var a = 0 / -3;
a // -0
a.toString() // 0
a + "" // 0
String( a ) // 0
JSON.stringify( a ) // 0
그런데 반대로 문자열 -0에서 숫자화 시키면 그대로 -0 이다.
+"-0"; // -0
Number( "-0" ); // -0
JSON.parse( "-0" ); // -0
-0을 비교 연산할 때도 특이하다.
연산자 사용시 무조건 0과 -0은 같다 라는 결과가 나온다.
var a = 0;
var b = 0 / -3;
a == b; // true
-0 == 0; // true
a === b; // true
-0 === 0; // true
0 > -0; // false
a > b; // false
0과 -0을 판별하려면 아래와 같은 함수로 판별 가능하다.
function isNegZero(n) {
n = Number( n );
return (n === 0) && (1 / n === -Infinity);
}
isNegZero( -0 ); // true
isNegZero( 0 / -3 ); // true
isNegZero( 0 ); // false
-0을 만든 이유
값의 크기로 어떤 정보(예: 애니메이션 프레임당 넘김 속도)와 그 값의 부호로 또 다른 정보(예: 넘김 방향)를 동시에 나타내야 하는 애플리케이션이 있기 때문이다.
어떤 변숫값이 0에 도달하여 부호가 바뀌는 순간, 그 직전까지 이 변수의 이동 방향은 무엇인지 알 수가 없으므로 부호가 다른 두 0은 유용하다.
즉, 잠재적인 정보 소실을 막기 위한 것.