Number.isNaN()
Tests whether a value is the number NaN, without coercing anything else.
Number.isNaN(value)- Added in JavaScript ES2015
Parameters
| Parameter | Type | Description |
|---|---|---|
$value | any | The 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
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.
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 zeroFinding NaN in an array
indexOf uses strict equality and so can never locate NaN; includes(), findIndex() with Number.isNaN, and filter() all work.
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.
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