Number.isNaN()

Tests whether a value is the number NaN, without coercing anything else.

Signature
Number.isNaN(value)
  • Added in JavaScript ES2015

Parameters

ParameterTypeDescription
$valueanyThe value to be tested for NaN.

Return value

boolean`true` if the value is a number with the value NaN, `false` otherwise.

NaN is the only value in JavaScript that is not equal to itself, so x === NaN can never be true and is always a bug. Number.isNaN() is the reliable test: it returns true for exactly one thing, the number NaN.

The difference from global isNaN()

The global isNaN() coerces its argument first, so it really answers "would this become NaN if I converted it?" That gives isNaN("blabla") === true and isNaN(undefined) === true even though neither value is NaN, and — more confusingly — isNaN(null) === false because null converts to 0. Number.isNaN() returns false for all three. Reach for the global only when you deliberately want the conversion, and write Number.isNaN(Number(x)) instead so the coercion is visible in the code.

When to reach for it

Immediately after parseInt(), parseFloat(), Number() or any arithmetic on values that might not be numeric. If you also want to rule out Infinity, use Number.isFinite(), which covers both cases in one call.

A modern alternative for finding NaN in an array is Object.is(x, NaN), which uses the SameValue algorithm, or arr.includes(NaN), which uses SameValueZero. Both match NaN where indexOf does not.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Detect a failed parseInt() or Number() conversion
  • Filter NaN out of a computed array before averaging
  • Assert a numeric field survived a transformation intact

Frequently asked questions

Why can't I use x === NaN?

NaN is the only value not equal to itself under ===, so that comparison is always false. Use Number.isNaN(x) or Object.is(x, NaN) instead.

What is the difference between Number.isNaN() and isNaN()?

Number.isNaN() returns true only for the actual NaN value, while the global isNaN() converts its argument first, so isNaN('blabla') is true and isNaN(null) is false.

How do I find NaN inside an array?

Use includes(NaN) or findIndex(Number.isNaN). indexOf(NaN) always returns -1 because it compares with strict equality.

More examples

Checking a conversion actually worked

Number.isNaN() catches genuine conversion failures, but empty strings and empty arrays convert cleanly to 0, so they need a separate guard if you want them rejected.

Example · javascript
function toNumber(input) {
  const n = Number(input);
  return Number.isNaN(n) ? null : n;
}

console.log(toNumber('42')); // 42
console.log(toNumber('4.5kg')); // null
console.log(toNumber('')); // 0 — empty string converts to zero
console.log(toNumber(undefined)); // null
console.log(toNumber([])); // 0 — empty array converts to zero

Finding NaN in an array

indexOf uses strict equality and so can never locate NaN; includes(), findIndex() with Number.isNaN, and filter() all work.

Example · javascript
const data = [1, NaN, 3];

console.log(data.indexOf(NaN)); // -1 — strict equality never matches
console.log(data.includes(NaN)); // true — SameValueZero does
console.log(data.findIndex(Number.isNaN)); // 1
console.log(data.filter((n) => !Number.isNaN(n))); // [1, 3]

Explicit coercion when you want it

Writing Number.isNaN(Number(v)) reproduces the global isNaN() behaviour while making the conversion step obvious to the next reader.

Example · javascript
const raw = ['10', 'ten', '3.5', null];

for (const v of raw) {
  console.log(
    JSON.stringify(v),
    'strict:', Number.isNaN(v),
    'coerced:', Number.isNaN(Number(v)),
  );
}
// "10"   strict: false coerced: false
// "ten"  strict: false coerced: true
// "3.5"  strict: false coerced: false
// null   strict: false coerced: false

Discussion

  • Be the first to comment on this lesson.