isNaN
is a nice function that checks if a value is not a number but has been the source of many sleepless nights and wasted weekends for developers. The reason for this is that isNaN
is not a reliable way to check if a value is not a number. Let me show you some examples:
Example 1
This is the expected behavior of isNaN. It returns true if the value is not a number and false if it is a number. In this case, ‘hello’ is not a number so isNaN returns true. So far so good.
isNaN('hello') // true
Example 2
This is where things start to get weird. The value is not a number but isNaN
returns false.
isNaN('123') // false
This is because isNaN
converts the value to a number before checking if it is not a number. In this case, ‘123’ is converted to 123 which is a number so isNaN
returns false. So if you want to check if a value is not a number, you can use the following function:
Example 3
How about null
? It is not a number so isNaN
should return true right? Wrong. It returns false.
isNaN(null) // false
null
is converted to 0 before checking if it is not a number. Since 0 is a number, isNaN
returns false.
Example 4
What if your value happens to be undefined
?
isNaN(undefined) // true
This is because undefined
is converted to NaN
before checking if it is not a number. Since NaN
is not a number, isNaN returns true. In this case, isNaN
works as expected.
Example 5
What if your value happens to be true
or false
which are not numbers or so you thought?
isNaN(true) // false
isNaN(false) // false
isNaN will “helpfully” convert true
to 1 and false
to 0 before checking if they are not numbers. Since 1 and 0 are numbers, isNaN
returns false.
Example 6
Have you ever mistakenly passed in ""
or " "
to isNaN
? You are in for a surprise.
isNaN("") // false
isNaN(" ") // false
The “brilliant” isNaN
function will convert ""
and " "
to 0 before checking if they are not numbers. Since 0 is a number, isNaN returns false.
Example 7:
So for whatever reason, you find yourself checking if a Date object is not a number. What do you think will happen?
isNaN(new Date()) // false
That’s right. isNaN
will convert the Date object to a number before checking if it is not a number. Since the Date object is converted to the number of milliseconds since January 1, 1970, 00:00:00 UTC, it is definitely a number so isNaN returns false.
Example 8
[]
and {}
behave differently when passed to isNaN
further adding to the confusion.
isNaN({}) // true
isNaN([]) // false
{}
is converted to NaN
before checking if it is not a number. Since NaN
is not a number, isNaN
returns true. On the other hand, []
is converted to 0 before checking if it is not a number. Since 0 is a number, isNaN
returns false.
Conclusion:
If you want to save yourself from a lot of headaches, you should know that isNaN
is a very unreliable way to check if a value is not a number. If you want to check if a value is not a number, you can use the following function:
function isNotANumber(value) {
return typeof value === 'number' && isNaN(value);
}
This function checks if the value is a number and if it is, it checks if it is NaN
. If it is NaN
, it returns true. Otherwise, it returns false.
isNotANumber('hello') // true
isNotANumber('123') // true
isNotANumber(null) // true
isNotANumber(undefined) // true
isNotANumber(true) // true
isNotANumber(false) // true
isNotANumber("") // true
isNotANumber(" ") // true
isNotANumber(new Date()) // true
isNotANumber({}) // true
isNotANumber([]) // true