JavaScript / isNaN()과 Number.isNaN() 차이와 NaN 검사
isNaN(value)는 값을 숫자로 변환한 결과가 NaN인지 검사합니다. 원래 값 자체가 실제 NaN인지 확인하려면 자동 변환하지 않는 Number.isNaN(value)를 사용하세요. 어느 쪽도 “입력값이 올바른 유한한 숫자인가”라는 질문 전체를 대신하지는 않습니다.
NaN과 숫자가 아닌 문자열은 다릅니다
isNaN(NaN); // true
isNaN("문자"); // true: 숫자 변환 결과가 NaN
Number.isNaN(NaN); // true
Number.isNaN("문자"); // false: 문자열 자체는 NaN 값이 아님
NaN은 Not-a-Number의 약자로, 0 / 0 같은 계산이나 Number("문자") 같은 변환에서 얻을 수 있는 특수한 Number 값입니다. "NaN"이라는 문자열과도 다릅니다. typeof NaN은 "number"를 반환하므로, 자료형 검사만으로 NaN을 제외할 수 없습니다.
전역 함수 isNaN()는 내부에서 숫자 변환을 수행합니다. 반면 Number.isNaN()는 숫자 자료형의 NaN 값일 때만 참입니다. MDN의 isNaN() 설명과 Number.isNaN() 설명은 두 판단 범위를 구분합니다.
| 값 | isNaN() |
Number.isNaN() |
|---|---|---|
NaN |
true |
true |
"문자" |
true |
false |
undefined |
true |
false |
"12" |
false |
false |
"" |
false |
false |
null |
false |
false |
Infinity |
false |
false |
빈 문자열과 null은 숫자 0으로 변환될 수 있어서 전역 함수에서 false가 나옵니다. 이 결과를 “사용자가 숫자를 입력했다”로 해석하면 안 됩니다. 또한 "123 * 123"은 산술식이 아니라 문자열이므로 일반 숫자 변환은 이를 계산해 주지 않습니다. 입력을 계산시키기 위해 eval()을 사용할 필요는 없습니다.
정상 값·NaN·Infinity를 비교하는 전체 예제
다음 코드를 nan-check.html에 저장하고 브라우저에서 여세요. 세 버튼은 나눗셈의 두 피연산자를 고정해 정상적인 수, NaN, 무한대를 각각 만듭니다. 피연산자는 연산의 대상이 되는 값입니다. 출력에는 문자열 삽입용 textContent를 사용합니다.
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>NaN과 Infinity 구분</title>
</head>
<body>
<h1>나눗셈 결과 검사</h1>
<button type="button" data-a="6" data-b="2">6 ÷ 2</button>
<button type="button" data-a="0" data-b="0">0 ÷ 0</button>
<button type="button" data-a="1" data-b="0">1 ÷ 0</button>
<pre id="output"></pre>
<script>
const output = document.getElementById("output");
function show(a, b) {
const value = a / b;
output.textContent = [
`${a} / ${b} = ${value}`,
`typeof: ${typeof value}`,
`isNaN: ${isNaN(value)}`,
`Number.isNaN: ${Number.isNaN(value)}`,
`Number.isFinite: ${Number.isFinite(value)}`
].join("\n");
}
document.querySelectorAll("button[data-a]").forEach((button) => {
button.addEventListener("click", () => {
show(Number(button.dataset.a), Number(button.dataset.b));
});
});
show(6, 2);
</script>
</body>
</html>
처음과 ‘6 ÷ 2’를 누른 결과는 3입니다. 두 NaN 검사는 false, 유한성 검사는 true입니다. ‘0 ÷ 0’을 누르면 NaN 검사는 모두 true가 되고 유한성 검사는 false입니다. ‘1 ÷ 0’은 Infinity이므로 NaN 검사는 false지만 유한성 검사도 false입니다.
이 실습은 “NaN이 아니다”와 “유한한 숫자다”가 다르다는 점을 보여 줍니다. 같은 출력 항목을 유지한 채 버튼만 바꾸어 비교하고, 정상 상태로 돌아가려면 ‘6 ÷ 2’를 누르세요. JavaScript의 Number 나눗셈에서는 0으로 나눴다고 이 예제 전체가 예외로 중단되는 것은 아닙니다.
NaN을 비교하거나 입력값을 검증할 때
NaN === NaN; // false
NaN == NaN; // false
Number.isNaN(NaN); // true
NaN은 자기 자신과도 같음 비교가 성립하지 않습니다. value === NaN으로 찾으려 하지 말고 Number.isNaN(value)로 의도를 드러내세요. 단, 이 함수가 false라는 이유만으로 문자열·객체·무한대를 전부 계산 가능한 유한한 Number라고 판단하면 안 됩니다.
입력란을 검사한다면 먼저 빈 값과 허용 형식을 확인하고 숫자로 변환한 뒤 Number.isFinite()를 적용하는 방법을 검토하세요. 정수 여부와 허용 범위도 필요에 따라 별도로 검사합니다. isFinite()와 Number.isFinite() 비교 글에는 변환 전후의 입력값을 같은 조건에서 검사하는 전체 예제가 있습니다.
전역 isNaN()는 숫자 변환 과정에서 Symbol이나 BigInt 같은 값에 TypeError를 낼 수도 있습니다. 변환을 원하지 않는 데이터 처리에서는 Number.isNaN()처럼 검사 목적이 분명한 함수를 선택하고, 검증과 변환을 뒤섞지 않는 것이 좋습니다.




