In Javascript, we have numerous ways to check if something is or is not a number. This is a particularly common task in Javascript, where there is dynamic typing, resulting in some unexpected things being classified as numbers. Typescript fixes some of these issues, but in this guide we'll cover how to check if something is a number in Javascript, and the pitfalls you should avoid when trying to do that.
Introducing isNaN
NaN
is a special value in Javascript which stands for "Not a Number". If you try to parse a text string in Javascript as an int
, you'll get NaN:
let x = parseInt("hello") // Returns NaN
NaN
in itself is kind of confusing, and you don't always get results you would expect. NaN
, for example, does not equal any other value, including itself. Testing this out will always return false:
5 === NaN // false
NaN === NaN // false
"foo" === NaN // false
You might think this all makes sense, until you try to run typeof NaN
- which returns number
. So it turns out, that NaN
is of type 'number' in Javascript after all:
typeof NaN // 'number'
Ignoring these peculiarities, Javascript comes with a built in function to test if something is "not a number" known as isNaN
. This function can easily be used to determine if a something would evaluate to NaN
if it was run through something like parseFloat
:
isNaN("hello") // true
isNaN(5) // false
isNaN({}) // true
isNaN(() => {}) // true
Since isNaN
checks if something is not a number, we can use !isNaN
to test if something is a number. For example, !isNaN(5)
is an easy way to test if 5
is a number:
!isNaN(5)
isNaN
makes sense in most cases, but since it parses numbers, it can cause some unexpected side effects. For example, Number(1n)
on BigInt
types throws an error, and therefore throws an error on isNaN
too:
isNaN(1n) // throws error
To resolve some of these problems, Javascript just made a new method, called Number.isNaN
. It's mostly the same, only it won't coerce the type to a number.
Number.isNaN vs isNaN
They are commonly thought to be the same, but isNaN
and Number.isNaN
work differently. isNaN
essentially parses the input, and tries to make a number out of it. That's why you see problems when you try to do isNaN(1n)
, since Number(1n)
throws an error. Instead, you can use Number.isNaN()
The difference between isNaN
and Number.isNaN
is that Number.isNaN
does not try to coerce the input into a number. Unlike isNaN
, it simply takes the input and confirms if it is equal to NaN
or not. That makes
So all of the following will return false, since none of them are exactly equal to NaN
:
Number.isNaN({}) // false
Number.isNaN("hello") // false
Number.isNaN(() => {}) // false
Number.isNaN("5") // false
while the following will return true, since they do return NaN
:
Number.isNaN(5 / "5") // true
Number.isNaN(parseFloat("hello")) // true
Either Number.isNaN
or isNaN
will solve most of your number checking needs, but there is one additional way to check if something is a number in Javascript
Using isInteger and isSafeInteger to check a number in Javascript
As well as isNaN
and Number.isNaN
, the methods Number.isInteger
and Number.isSafeInteger
can help you determine if something is simply an integer, with no decimal points. Just like Number.isNaN
, both of these methods do not try to evaluate the contents as a number. That means passing in a string will always return false, while a normal integer will pass the test:
Number.isInteger("5") // false
Number.isInteger(5) // true
Number.isSafeInteger("5") // false
Number.isSafeInteger(5) // true
isSafeInteger
differs from isInteger
by checking that the number falls outside the bigint
range - i.e. within -2^53
and 2^53
- so for most use cases isInteger
will do the job.
Using typeof to check if something is a number in Javascript
The final way to check if something is a number is to use typeof
- again, this may fit your needs better for some cases, since typeof Math.sqrt(-1)
returns number
, rather than NaN
- however things like 1n
will still show a type of bigint
:
typeof Math.sqrt(-1) // 'number'
typeof parseFloat("35") // 'number'
typeof 35 // 'number'
typeof 1n // 'bigint'
However, be careful since it is quite unreliable. Since typeof NaN
returns number
, you can run into some unexpected situations which you will generally want to avoid. As such, Number.isNaN
remains probably the best way to check if something is or isn't a number.
Here are a few unexpected typeof
situations you'll generally want to avoid:
typeof parseFloat("hello") // 'number' - since NaN is a number
typeof 5 / "5" // 'NaN' - since this evaluates typeof 5, and then divides by "5"
typeof (5 / "5") // 'number' - since this evaluates as NaN, which is a number
typeof NaN // 'number' - since NaN is of type number
typeof "5" // 'string'
Conclusion
Checking if something is or is not a number in Javascript has some complexities, but it's generally straight forward. The key points are:
-
isNaN
is commonly used, but will evaluate its input as a number, which may cause some inputs are incorrectly judged to beNaN
or throw an error. -
Number.isNaN
is a robust version ofisNaN
, which checks if something is exactly equal toNaN
. It does not evaluate its contents as a number -
typeof
can tell you if something is anumber
or not, but it may lead to some unexpected situations, sinceNaN
is also of type number.
I hope you've enjoyed this guide on checking if something is a number in Javascript. You can also check out more of my Javascript content here.