# How to check if a value is a number

JavaScript polyfill, by Bjørn A. Johansen,*Monday, March 17th, 2014*

There are different approaches to getting to the answer to this question regardless of what you mean by checking if a value is a number. If you are trying to determine if a value is numeric, meaning that it can be parsed to a numeric value, then you can use the following function;

- var isNumeric = function (n) {
- return !isNaN(parseFloat(n)) && isFinite(n);
- };

This will return true for both strings consisting of only of numbers and actual finite numbers, which is great if that is sufficient for your task. But if you need more precision, and only can accept actual number values, you can use the following function;

- var isNumber = function (n) {
- return isFinite(n) && +n === n;
- };

This function (*isNumber*) will only return true, if the value is an actual finite number. These two examples should cover your needs when it comes to checking if a value is a number or numeric, but how do they work and are these the only ways to make this test? Why can we just use *isNaN*? And why do we need *isFinite*? To answer this, lets look at what the specifications says about these methods.

### Why not just use isNaN?

First of, you might be tempted to pose the question; why we do not just use the build in *isNaN()* method to do the check? The reason for this, is that the *isNaN()* method works as follows: (*The definitions are from the ECMAScript-262 standard section 15.1.2.4*)

- If ToNumber(
*number*) is**NaN**, return**true**. - Otherwise, return
**false**

Here the *ToNumber* operation corresponds to doing conversion with the + (*plus*) operator, which we can try in the browser console, on a few carefully selected values;

```
>+'Durian';
NaN
>+' ';
0
>+Infinity
Infinity
>+null
0
>+true
1
```

This illustrates the problem with *isNaN* in that even though the string 'Durian' correctly returns *NaN* the empty string ' ' returns 0, and even more surprisingly *+null* returns 0! This is bad if you really need to be sure that the given value is in fact a number. Furthermore we see that *+Infinity* returns *Infinity* which some might argue is correct, but which no matter how you look at it, does not help in our situation. Rather the opposite.

### Trying to fixt isNaN with parseFloat

At this point we see that most of our problems stem from values being *wrongly* converted to numerical values, so to deal with this why not take advantage of the build in method *parseFloat*, which works something along the lines of; (*this is not a complete of the steps of workings for the parseFloat method. However, you can find the full list in the ECMAScript-262 documentation section 15.1.2.3*)

- Let
*inputString*be ToString(*string*). - Let
*trimmedString*be a substring of*inputString*... (*no leading white spaces*) - If neither
*trimmedString*nor any prefix of*trimmedString*satisfies the syntax of a*StrDecimalLiteral*, return**NaN**. - ...

All we need to get from the steps that define how the method works is, that the trimmed string needs to satisfy the syntax of a *StrDecimalLiteral*, which essentially means that what is left after trimming away leading white spaces can, when converted to a number represent an actual number. It is obvious from this, that if we apply these rules to the before tested values the *+' '*, *+null*, and *+true* expressions will now return *NaN*. What is less obvious is, that *+Infinity* still will pass as a number, which is technically correct, but practically not very convenient. Another problem occurs when we realize, that *parseFloat* works from left to right, which means that, "d3" will return *NaN* while "3d" will return 3! This is no good as neither the string "3d" or "d3" are numerical.

### Coincidentally fixing the problem with isFinite

This is a situation where an obvious idea would be to turn to the build in method *isFinite* for help. At least we expect it to get rid of the problem of *Infinity* parsing as a number, so lets look at how it works; (*again this definition is taken from the ECMAScript-262 standard*)

- If ToNumber(
*number*) is**NaN**,**+∞**or**-∞**, return**false**. - Otherwise, return
**true**.

If we apply these conditions to the above, we see that it helps us get rid of the problem with *Infinity*, as the specifications says that the *isFinite* method will return false if it encounters an infinite number. The question that now remains is; does it help us with the "3d"/"d3" problem? If you remember from talking about the *isNaN*, the ToNumber method is equivalent to applying the + operator to the string, and if we try that in the console, we see, that both +"3d" and +"d3" return *NaN*. This is the argument for why the very first mentioned *isNumeric* function works, but now knowing why it works poses a new question.

### Do we really need isNaN?

Looking at the specifications above, it is obvious that the *isNaN* and *isFinite* methods work in very similar ways. The *isFinite* method is just a negation of *isNaN* with the added condition that it also checks for infinity. This of course means, that you can write the *isNumeric* function replacing !*isNaN* with *isFinite* and it will behave exactly the same, so technically we do not need *isNaN* except maybe for readability.

If you look through the ECMAScript specifications you will find, that you can write the *isNumberic* function in yet another way, but it involves an controversial part of the JavaScript language; the double equal (==) comparison operator.

- var isNumeric = function (n) {
- return isFinite(n) && parseFloat(n) == n;
- };

If we look at how the double equal comparison operator works in our situation, which is equating using *The Abstract Equality Comparison Algorithm*, we find at step 4 and 5; (*this is taken from the ECMAScript-262 standard section 11.9.3*)

- If Type(
*x*) is Number and Type(*y*) is String, return the result of the comparison x == ToNumber(*y*). - If Type(
*x*) is String and Type(*y*) is Number, return the result of the comparison ToNumber(x) ==*y*.

What this means in our context is, that since anything parsed to the *parseFloat()* method either returns a number or *NaN* the result will only be a comparison between either *NaN* and some other value, which will always return false, or it will be between a number and some other value, which will return true if ToNumber of that value is a number. With this said, using the double equal comparison operator is discouraged, as its logic of conversion is not easy to remember. If you instead use the triple equal (===) comparison operator you will get the same functionality as in the *isNumber* function. However we can not just remove an equal from the *isNumber* method and expect it to behave in the same way as the *isNumeric* method as, because we do no longer do strict comparison, we need to guard our self from situations like an empty string, which prefixed by + returns 0 and therefore would pass as being numeric. So when it comes to numbers in JavaScript we have to step carefully.