How JavaScript Treats NaN Equality Comparisons
In JavaScript, NaN (Not-a-Number) exhibits a unique
behavior where it is never equal to any value, including itself, when
evaluated with standard equality operators. Regardless of whether you
use the loose equality operator (==) or the strict equality
operator (===), any direct comparison involving
NaN will return false. This article explains
the specification behind this behavior, demonstrates how equality
operators handle NaN, and details the correct methods to
check for NaN values reliably.
The Behavior of Equality Operators with NaN
When comparing NaN to any value using either loose
(==) or strict (===) equality, the result is
always false:
console.log(NaN == NaN); // false
console.log(NaN === NaN); // false
console.log(NaN == 0); // false
console.log(NaN === undefined); // false
console.log(NaN == false); // falseConversely, the inequality operators (!= and
!==) will always evaluate to true when
comparing NaN to anything, including another
NaN:
console.log(NaN != NaN); // true
console.log(NaN !== NaN); // trueWhy NaN Is Not Equal to NaN
JavaScript adheres to the IEEE 754 floating-point
standard for representing numbers. Under this standard,
NaN does not represent a specific, distinct numeric value;
rather, it signifies an undefined, unrepresentable, or erroneous
mathematical result (such as 0 / 0 or
Math.sqrt(-1)).
Because two distinct invalid operations do not necessarily yield the
same underlying mathematical condition, the IEEE 754 specification
explicitly dictates that NaN must compare unequal to all
values, including itself.
How to Correctly Check for NaN
Because standard equality checks fail to identify NaN,
JavaScript provides specialized methods for detection.
1. Number.isNaN()
(Recommended)
Introduced in ECMAScript 2015 (ES6), Number.isNaN() is
the most robust way to check for NaN. It returns
true only if the passed value is both of the type
Number and evaluates to NaN, without
performing implicit type coercion.
Number.isNaN(NaN); // true
Number.isNaN("hello"); // false (string, not coerced)
Number.isNaN(undefined); // false2. Object.is()
The Object.is() method determines whether two values are
the same value. Unlike ===, it treats NaN as
equal to NaN.
Object.is(NaN, NaN); // true
Object.is(NaN, 0); // false3. The Self-Comparison Trick
Because NaN is the only value in JavaScript that is not
equal to itself, you can verify if a variable is NaN using
strict inequality against itself:
function isValueNaN(val) {
return val !== val;
}
console.log(isValueNaN(NaN)); // true
console.log(isValueNaN(123)); // false
console.log(isValueNaN("text")); // false4. Global isNaN()
(Use with Caution)
The global isNaN() function checks if a value is
NaN, but it first coerces the argument to a number. This
can produce false positives for non-numeric values that cannot be parsed
into numbers.
isNaN(NaN); // true
isNaN("text"); // true (coerced to NaN, often unintended)
isNaN(undefined); // true (coerced to NaN)
isNaN("123"); // false (coerced to 123)