NaN in JavaScript: A Number That Means Something Went Wrong
A deeper look at NaN in JavaScript, explaining why it’s still a number, how it propagates through calculations, and how to handle it safely in real applications.
At some point while working with numbers in JavaScript, you’ll encounter a value that feels contradictory.
NaNIt literally stands for “Not-a-Number”.
And yet, when you check it:
typeof NaN // "number"This is one of those moments where JavaScript seems to break its own logic. How can something called not a number still be a number?
The answer reveals something deeper about how JavaScript handles computation and failure.
NaN Is Not an Error — It’s a Result
In many languages, invalid numeric operations throw errors.
In JavaScript, they usually don’t.
Instead, JavaScript returns a special value:
NaNYou’ll see it in situations like:
0 / 0
Math.sqrt(-1)
Number("hello")
parseInt("abc")All of these are operations where JavaScript expects a number but cannot produce a valid one.
Rather than stopping execution, JavaScript continues running and uses NaN as a signal:
“This calculation failed to produce a meaningful number.”
Why NaN Is Still a Number
Under the hood, JavaScript uses the IEEE 754 floating-point standard for numbers.
In that system, NaN is a legitimate numeric value. It’s part of how computers represent undefined or unrepresentable results in arithmetic.
So from the engine’s perspective:
NaN ∈ NumberThat’s why:
typeof NaN // "number"The name is misleading. A more accurate mental model would be:
NaN is a failed number, not a non-number.
NaN Propagates Through Calculations
Once NaN appears, it tends to spread.
NaN + 5 // NaN
NaN * 10 // NaN
1 / NaN // NaNThis is intentional.
If one part of a calculation is invalid, the entire result becomes unreliable. So JavaScript keeps returning NaN to signal that something went wrong earlier.
The Strange Behavior: NaN Is Not Equal to Itself
One of the most surprising behaviors:
NaN === NaN // falseThis feels wrong at first.
But the reasoning is subtle. Since NaN represents an unknown or invalid result, JavaScript treats comparisons involving it as unreliable.
So instead of saying two invalid values are equal, it simply returns false.
How to Check for NaN Properly
Because of that behavior, this does not work:
value === NaN // always falseInstead, JavaScript provides a specific method:
Number.isNaN(value)This is the safest and most explicit way to check for NaN.
There’s also a global function:
isNaN(value)But it performs type coercion, which can lead to confusing results:
isNaN("hello") // trueThis happens because "hello" gets converted to NaN first.
So in modern JavaScript, prefer:
Number.isNaN(value)Where NaN Usually Comes From
In real applications, NaN often appears because of unexpected input.
For example:
const input = "123px"
Number(input) // NaNOr:
const value = undefined
value * 2 // NaNThese situations usually indicate:
- invalid parsing
- missing data
- incorrect assumptions about input types
So NaN is often a signal that something upstream needs attention.
Handling NaN in Practice
There are a few practical strategies for dealing with NaN.
First, validate inputs before performing calculations.
const num = Number(input)
if (Number.isNaN(num)) {
// handle invalid input
}Second, provide fallback values when necessary.
const result = Number(input)
const safeValue = Number.isNaN(result) ? 0 : resultThird, avoid relying solely on typeof.
typeof NaN // "number"This tells you the category, but not whether the value is valid.
So always combine checks:
typeof value === "number" && !Number.isNaN(value)A Subtle but Important Distinction
It’s easy to think of NaN as an error.
But JavaScript treats it differently.
Errors stop execution.
NaN allows execution to continue, while quietly carrying the information that something went wrong.
This design makes JavaScript more flexible, but also places more responsibility on developers to validate and handle data carefully.
A Better Way to Think About It
Instead of thinking:
“NaN means not a number”
It’s more useful to think:
“NaN means a numeric operation failed”
That shift in perspective makes its behavior feel much more consistent.
And once that clicks, NaN stops feeling like a strange exception and starts feeling like a deliberate part of the system.