NaN
은 Not-A-Number
(숫자가 아님)을 나타내는 전역 객체의 속성이다. Number.NaN
의 값과 같다. 최신 브라우저에서 NaN
은 설정 불가, 쓰기 불가한 속성이다.
NaN
을 반환하는 경우는 다음과 같다.
parseInt('blahblah')
, Number(undefined)
Math.sqrt(-1)
NaN
인 경우 ex) (7 ** NaN)
(0 * Infinity)
("안녕" / 3)
💡
Math.sqrt()
: 제곱근(루트)을 구하는 메서드**
: 거듭 제곱 연산자 ex)2 ** 3
의 연산결과는8
이다.
NaN
판별
NaN
은 다른 모든 값과 비교(==
, !=
, ===
, !==
)했을 때에도 같지 않고, 다른 NaN
과도 같지 않다.NaN
을 판별할 때는 isNaN()
또는 Number.isNaN()
을 사용하면 가장 분명하게 NaN
을 판별할 수 있다.NaN
만이 자기자신과 비교했을 때 같지 않다.NaN === NaN; // false
Number.NaN === NaN; // false
isNaN(NaN); // true
isNaN(Number.NaN); // true
Number.NaN
은 Not-A-Number
(숫자가 아님)을 나타내며, NaN
과 같다.
NaN
과Number.NaN
은Not-A-Number
를 나타낸다는 점에서 같다. 다만 NaN은 비교연산을 했을 때 어떤 다른 NaN과도 같지 않다는 점을 기억하자.
isNaN()
vs Number.isNaN()
isNaN(value)
과 Number.isNaN(value)
은 value가 NaN
인지 판별할 때 쓰인다. 그러나 둘은 분명한 차이점이 존재한다.
isNaN('hello world'); // true
Number.isNaN('hello world'); // false
'hello world'
는 숫자가 아닌 문자열이다. 일단 숫자가 아니므로(Not-A-Number) isNaN()
에선 true
를 리턴하는 것 같다. 그런데 isNaN()
과 같은 기능을 할 것같은 Number.isNaN()
에선 왜 false
를 리턴하는걸까? 이는 두 메서드가 NaN인지 판별하는 방식이 서로 다르기 때문이다.
isNaN()
NaN
이거나, 값을 숫자로 변환했을 때 NaN
이면 참(true
)을 리턴한다.isNaN()
은 인자를 숫자로 변환하는 과정을 거쳐 판별한다.Number.isNaN()
NaN
이어야만 참(true
)을 리턴한다.isNaN()
에서는 인자를 Number
로 변환한 뒤, NaN
이면 true
를 리턴하기 때문에 isNaN('hello world')
의 경우 true
이다. Number.isNaN()
에서는 false
를 리턴한다. 왜냐하면 문자열은 숫자가 아닌 건 맞지만, 그 자체로 NaN
이 아니기 때문이다. 문자열인 'hello world'
은 그 자체로는 NaN
이 아니다.
아래 예제에서 출력될 결과를 예상해보자.
isNaN(null);
Number.isNaN(null);
isNaN('25');
isNaN('25.25');
Number.isNaN(NaN);
Number.isNaN(Number.NaN);
Number.isNaN({});
Number.isNaN('hello');
Number.isNaN(NaN);
Number.isNaN('happy' / 'coding');
isNaN({});
isNaN('hello');
isNaN(NaN);
isNaN('happy' / 'coding');
정답은 아래와 같다.
isNaN(null); // false
Number.isNaN(null); // false
isNaN('25'); // false // "25"는 숫자 25로 변환된다.
isNaN('25.25'); // false // "25.25"는 숫자 25.25로 변환된다.
Number.isNaN(NaN); // true
Number.isNaN(Number.NaN); // true
Number.isNaN({}); // false, {} is not NaN
Number.isNaN('hello'); // false, 'hello' is not NaN
Number.isNaN(NaN); // true, NaN is NaN
Number.isNaN('happy' / 'coding'); //true, 'happy'/'coding' is NaN -> NaN is NaN
isNaN({}); // true, {}는 숫자로 변환하면 NaN이다.
isNaN('hello'); // true, 'ponyfoo' is not a number
isNaN(NaN); // true, NaN is not a number
isNaN('happy' / 'coding'); // true, 'happy'/'coding' is NaN -> NaN is not a number
(추가)여러가지 값을 숫자로 변환했을 때 어떻게 되는지 알아보자.
// 여러가지 값을 숫자로 변환해보자.
Number(null); // 0 // null은 숫자로 변환하면 0이다.
Number(''); // 0
Number(' '); // 0
Number(false); // 0
Number(''); // 0
Number([]); // 0
Number({}); // NaN
NaN과 Infinity
isNaN(5 / 0); // false // (5/0) is Infinity -> Infinity is a number
isNaN(0 / 0); // true // (0/0) is NaN -> NaN is NaN
Number.isNaN(5 / 0); // false // Infinity is not NaN
Number.isNaN(0 / 0); // true // (0/0) is NaN -> NaN is NaN
0 / 0; // NaN
5 / 0; // Infinity
-5 / 0; // -Infinity
0 * Infinity; // NaN
1 * Infinity; // Infinity
Number(Infinity); // Infinity
Number(-Infinity); // -Infinity
💡 자바에서는 정수를 0으로 나누면 에러가 발생하지만, 자바스크립트에서는 0이 아닌 정수를 0으로 나눴을 때 에러가 발생하지 않고
Infinity
나-Infinity
가 반환된다.
NaN 과 배열 메서드
일부 배열 메서드에서는 NaN을 찾을 수 없다.
let arr = [2, 4, NaN, 12];
arr.indexOf(NaN); // -1 (false)
arr.includes(NaN); // true
arr.findIndex((n) => Number.isNaN(n)); // 2
👍👍