I donβt think any suggestions still really work. For example,
!isNaN(parseFloat(foo))
not because parseFloat() ignores trailing non-numeric characters.
To get around this, you can compare the return value with that returned with Number() (or, equivalently, with unary + , but I prefer casting explicitly):
parseFloat(foo) === Number(foo)
This will work if both functions return NaN , because NaN !== NaN is true .
Another possibility would be to first pass to the string, then to the number, and then check for NaN , i.e.
!isNaN(Number(String(foo)))
or equivalent, but less readable (but most likely faster)
!isNaN(+('' + foo))
If you want to exclude infinity values, use isFinite() instead of !isNaN() , i.e.
isFinite(Number(String(foo)))
Explicit listing via Number() is not really needed, because isNan() and isFinite() not accurately indicate the number - the reason !isNaN() does not work!
In my opinion, the most appropriate solution would be
isFinite(String(foo))
As Matthew noted, the second approach does not process strings that contain only spaces.
It's not hard to fix - use the code from Matthew's comment
isFinite(String(foo).trim() || NaN)
You will need to decide how much better this is than comparing the results of parseFloat() and Number() .