Fundamentalsbeginner
NaN and Number Edge Cases
Understanding NaN's self-inequality, floating-point precision issues, and safe ways to check for numeric validity.
NaN (Not-a-Number) is JavaScript's way of representing the result of an invalid or undefined numeric operation, and it has a genuinely strange property that trips up almost every developer at least once: NaN is the only value in JavaScript that is not equal to itself. This makes it a favorite interview gotcha because the fix is simple once you know it, but baffling if you don't.
NaN is like a person with no ID who can never prove they're the same person twice, even to themselves. Floating-point imprecision is like trying to represent 1/3 in decimal — you eventually have to round, and that tiny rounding error can snowball.
Key Concepts
1
NaN shows up from operations like 0 / 0, Number('abc'), or Math.sqrt(-1). Because NaN === NaN evaluates to false — a consequence of the IEEE 754 floating-point standard, which JavaScript's number type is built on — you cannot check for it with equality operators. Instead, Number.isNaN(value) is the correct, strict way to check, since it only returns true for the actual NaN value, not values that merely fail to convert. The older global isNaN() function is looser: it coerces its argument to a number first, so isNaN('hello') returns true even though 'hello' was never NaN to begin with, just non-numeric.
NaN0 / 0Number('abc')Math.sqrt(-1)NaN === NaN
2
Beyond NaN, JavaScript numbers are IEEE 754 double-precision floats, which means they cannot represent every decimal value exactly — this is why 0.1 + 0.2 === 0.3 is false (it actually equals 0.30000000000000004). This isn't a JavaScript bug specifically; it's shared by essentially every language using floating-point arithmetic, but it surprises newcomers regularly.
NaN0.1 + 0.2 === 0.3false0.30000000000000004
3
The practical fixes are to use Number.isNaN() for NaN checks, round or use an epsilon-based comparison for floating-point equality (Math.abs(a - b) < Number.EPSILON), and reach for BigInt when you need arbitrary-precision integers beyond Number.MAX_SAFE_INTEGER.
Number.isNaN()Math.abs(a - b) < Number.EPSILONBigIntNumber.MAX_SAFE_INTEGER