NaN

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

전역 NaN 속성은 Not-A-Number(숫자가 아님)를 나타냅니다.

시도해보기

function sanitize(x) {
  if (isNaN(x)) {
    return NaN;
  }
  return x;
}

console.log(sanitize("1"));
// Expected output: "1"

console.log(sanitize("NotANumber"));
// Expected output: NaN

Number.NaN와 동일한 숫자 값입니다.

Property attributes of NaN
쓰기 가능불가능
열거 가능불가능
설정 가능불가능

설명

NaN은 전역 객체의 속성입니다. 즉 전역 범위의 변수입니다.

최신 브라우저에서 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))

NaNNaN의 동작은 JavaScript에서 발명한 것이 아닙니다. 부동 소수점 산술의 의미(NaN !== NaN 포함)는 IEEE 754에 의해 지정됩니다. NaN의 동작은 다음과 같습니다.

  • NaN이 수학 연산에 포함된 경우 (그러나 비트 연산는 아님) 결과도 일반적으로 NaN 입니다. (아래의 counter-example 참조)
  • NaN이 관계 비교(>, <, >=, <=)의 피연산자 중 하나인 경우 결과는 항상 false입니다.
  • NaN은 ( ==, !=, ===!== 를 통해) 다른 NaN 값을 포함하여 다른 값과 같지 않은 것으로 비교됩니다.

NaN은 JavaScript의 falsy 값 중 하나이기도 합니다.

예제

NaN 판별

값이 NaN인지 확인하려면, Number.isNaN() 또는 isNaN()를 사용하여 값이 NaN인지 여부를 확인 할 수 있습니다. 또는 NaN은 자신과 같지 않다고 비교되는 유일한 값이므로 x !== x와 같은 자체 비교를 수행할 수 있습니다.

js
NaN === NaN; // false
Number.NaN === NaN; // false
isNaN(NaN); // true
isNaN(Number.NaN); // true

function valueIsNaN(v) {
  return v !== v;
}
valueIsNaN(1); // false
valueIsNaN(NaN); // true
valueIsNaN(Number.NaN); // true

그러나 isNaN()Number.isNaN()의 차이를 유의해야 합니다. isNaN은 현재 값이 NaN이거나, 숫자로 변환했을 때 NaN이 되면 참을 반환하지만, Number.isNaN은 현재 값이 NaN이어야만 참을 반환합니다.

js
isNaN("hello world"); // true
Number.isNaN("hello world"); // false

같은 이유로 BigInt 값을 사용하면 Number.isNaN()이 아닌 isNaN()에서 오류가 발생합니다.

js
isNaN(1n); // TypeError: Conversion from 'BigInt' to 'number' is not allowed.
Number.isNaN(1n); // false

또한 일부 배열 메서드는 NaN을 찾을 수 없는 반면에 다른 배열 메서드들은 찾을 수 있습니다. 즉, (indexOf(), lastIndexOf())는 NaN을 찾을 수 없지만, includes()는 값을 찾을 수 있습니다.

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

// 적절하게 정의된 조건자를 허용하는 메서드는 항상 NaN을 찾을 수 있습니다.
arr.findIndex((n) => Number.isNaN(n)); // 2

NaN과 그 비교에 대한 자세한 내용은 평등 비교 및 동일성를 참조.

눈에 띄게 구별되는 NaN 값

NaN이 자신과 동등하지 않은 데는 동기가 있습니다. IEEE 754 인코딩에서 지수 0x7ff와 0이 아닌 가수부가 있는 부동 소수점 숫자는 NaN이기 때문에 서로 다른 이진 표현을 가진 두 개의 부동 소수점 숫자를 생성할 수 있지만 둘 다 NaN입니다. JavaScript에서 typed arrays를 사용하여 비트 수준 조작을 수행할 수 있습니다.

js
const f2b = (x) => new Uint8Array(new Float64Array([x]).buffer);
const b2f = (x) => new Float64Array(x.buffer)[0];
// NaN의 byte 표현을 가져옵니다.
const n = f2b(NaN);
// 부호 비트이고 NaN에 중요하지 않은 첫 번째 비트를 변경합니다.
n[0] = 1;
const nan2 = b2f(n);
console.log(nan2); // NaN
console.log(Object.is(nan2, NaN)); // true
console.log(f2b(NaN)); // Uint8Array(8) [0, 0, 0, 0, 0, 0, 248, 127]
console.log(f2b(nan2)); // Uint8Array(8) [1, 0, 0, 0, 0, 0, 248, 127]

조용히 NaN 탈출

NaN은 수학적 연산을 통해 전파되므로 일반적으로 오류 조건을 감지하기 위해 계산이 끝날 때 한 번 NaN을 테스트하는 것으로 충분합니다. NaN이 자동으로 이스케이프되는 유일한 경우는 지수가 0거듭제곱을 사용할 때입니다. 그러면 기본값을 검사하지 않고 즉시 1이 반환됩니다.

js
NaN ** 0 === 1; // true

명세

Specification
ECMAScript® 2025 Language Specification
# sec-value-properties-of-the-global-object-nan

브라우저 호환성

Report problems with this compatibility data on GitHub
desktopmobileserver
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
Deno
Node.js
NaN

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support

같이 보기