gotchajavascriptModerate
NaN is not equal to itself in JavaScript
Viewed 0 times
NaN comparisonNumber.isNaNnot a numberNaN checkisNaN global
Problem
NaN !== NaN returns true. This means you can't check for NaN with equality operators. Also, typeof NaN === 'number', and NaN is the result of invalid math operations like 0/0 or parseInt('abc').
Solution
Use Number.isNaN() (not the global isNaN):
// BAD: global isNaN coerces to number first
isNaN('hello') // true (coerces to NaN)
isNaN(undefined) // true
// GOOD: Number.isNaN checks type AND value
Number.isNaN(NaN) // true
Number.isNaN('hello') // false
Number.isNaN(undefined) // false
// Self-comparison trick
function isNaN(x) { return x !== x; } // only NaN is not equal to itself
// Also useful
Number.isFinite(x) // false for NaN, Infinity, -Infinity
// BAD: global isNaN coerces to number first
isNaN('hello') // true (coerces to NaN)
isNaN(undefined) // true
// GOOD: Number.isNaN checks type AND value
Number.isNaN(NaN) // true
Number.isNaN('hello') // false
Number.isNaN(undefined) // false
// Self-comparison trick
function isNaN(x) { return x !== x; } // only NaN is not equal to itself
// Also useful
Number.isFinite(x) // false for NaN, Infinity, -Infinity
Why
IEEE 754 defines NaN as not equal to anything, including itself. This is because NaN represents 'the result of an undefined operation' — there are many ways to get NaN, and two NaN values don't necessarily represent the same failed operation.
Gotchas
- Global isNaN() coerces its argument to Number first — use Number.isNaN()
- Array.includes(NaN) returns true (uses SameValueZero), but indexOf(NaN) returns -1 (uses ===)
- JSON.stringify(NaN) produces 'null', not 'NaN'
Code Snippets
NaN checking
NaN === NaN // false
NaN !== NaN // true
// Global isNaN is broken
isNaN('hello') // true (!) — coerces to Number
// Number.isNaN is correct
Number.isNaN('hello') // false
Number.isNaN(NaN) // true
Number.isNaN(0 / 0) // trueContext
When checking for NaN values in JavaScript
Revisions (0)
No revisions yet.