프로그래밍/웹 관련

[javascript] NaN (Not a Number), isNaN(), Number.isNaN() 에 대하여

채윤아빠 2021. 5. 27. 09:20
728x90
반응형

NaN (Not a Number) 이란?

"NaN" (Not a Number)은 영문 그대로 숫자가 아닌 상태를 표시하는 전역 속성입니다.
그래서 그 자체는 상수처럼 불변이고, "NaN"은 서로 같지 않습니다.
"NaN" 은 "Number.NaN"와 동일합니다.

NaN == NaN
// false

NaN == Number.NaN
// false

NaN 값 비교하기

NaN과 비교하기 위하여 isNaN() 함수나 Number.isNaN() 함수를 이용할 수 있습니다.
그런데, 두 함수가 조금씩 차이가 있습니다.

isNaN() 함수의 경우 함수의 매개변수로 전달된 인자가 숫자로 변환이 가능한지를 확인하고, Number.isNaN() 함수는 인자 자체가 "NaN" 값인지를 확인합니다.

let a = 1;
isNaN(a) // false
Number.isNaN(a) // false

let b = '1';
isNaN(b) // false
Number.isNaN(b) // false

let c = 'k1';
isNaN(c) // true
Number.isNaN(c) // false
Number.isNaN(parseInt(c)) // true

두 함수간 또 다른 차이점은 BigInt 데이터를 다룰 때 입니다.
isNaN() 함수에 BigInt를 매개변수로 전달하면 오류가 발생합니다.

let a = 1n;
Number.isNaN(a); // false
isNaN(a); // TypeError: Cannot convert a BigInt value to a number

NaN을 반환하는 경우는?

NaN을 반환하는 상황은 다음과 같습니다.

  • 숫자로의 변환을 실패하였을 때
    • 예) parseInt("blabla"), Number(undefined)와 같은 명시적인 상황
    • 예) Math.abs(undefined)와 같은 암시적인 상황
  • 결과가 허수인 수학 계산식
    • 예) Math.sqrt(-1)
  • 정의할 수 없는 계산식
    • 예) 0 * Infinity, 1 ** Infinity, Infinity / Infinity, Infinity - Infinity
  • 피연산자가 NaN이거나 NaN으로 강제 변환되는 메서드 또는 표현식
    • 예) 7 ** NaN, 7 * "blabla"
    • 이것은 NaN이 전염성 있다는 것을 의미합니다.
  • 유효하지 않은 값이 숫자로 표시되는 기타 경우
    • 예) 잘못된 날짜 new Date("blabla").getTime(), "".charCodeAt(1)

배열에서의 NaN

배열 내부에 NaN이 포함되어 있다면, indexOf()나 lastIndexOf() 등의 함수로는 NaN을 찾을 수 없습니다.
대신 includes()로 NaN 포함여부를 확인할 수 있습니다.

const arr = [2, 4, NaN, 12];
console.log(arr.indexOf(NaN)); // -1
console.log(arr.includes(NaN)); // true

// 다음과 같이 배열에서 NaN의 위치를 찾을 수 있습니다.
console.log(arr.findIndex((n) => Number.isNaN(n))); // 2

참고자료