Checking if a value is a number in Javascript with isNaN()

Checking if a value is a number in Javascript with isNaN()

·

5 min read

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 peculiariies, 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) // true

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 global methods isInteger and 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:

isInteger("5") // false
isInteger(5) // true
isSafeInteger("5") // false
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 be NaN or throw an error.

  • Number.isNaN is a robust version of isNaN, which checks if something is exactly equal to NaN. It does not evaluate its contents as a number

  • typeof can tell you if something is a number or not, but it may lead to some unexpected situations, since NaN 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.

Did you find this article valuable?

Support Daily Dev Digest by becoming a sponsor. Any amount is appreciated!