Question
What's the cleanest, most effective way to validate decimal numbers in JavaScript?
Bonus points for:
- Clarity. Solution should be clean and simple.
- Cross-platform.
Test cases:
01. IsNumeric('-1') => true
02. IsNumeric('-1.5') => true
03. IsNumeric('0') => true
04. IsNumeric('0.42') => true
05. IsNumeric('.42') => true
06. IsNumeric('99,999') => false
07. IsNumeric('0x89f') => false
08. IsNumeric('#abcdef') => false
09. IsNumeric('1.2.3') => false
10. IsNumeric('') => false
11. IsNumeric('blah') => false
Answer
[@Joel's answer](https://stackoverflow.com/questions/18082/validate-numbers- in-javascript-isnumeric/174921#174921) is pretty close, but it will fail in the following cases:
// Whitespace strings:
IsNumeric(' ') == true;
IsNumeric('\t\t') == true;
IsNumeric('\n\r') == true;
// Number literals:
IsNumeric(-1) == false;
IsNumeric(0) == false;
IsNumeric(1.1) == false;
IsNumeric(8e5) == false;
Some time ago I had to implement an IsNumeric
function, to find out if a
variable contained a numeric value, regardless of its type , it could be a
String
containing a numeric value (I had to consider also exponential
notation, etc.), a Number
object, virtually anything could be passed to that
function, I couldn't make any type assumptions, taking care of type coercion
(eg. +true == 1;
but true
shouldn't be considered as "numeric"
).
I think is worth sharing this set of +30 unit tests made to numerous function implementations, and also share the one that passes all my tests:
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
P.S. [isNaN](https://developer.mozilla.org/en- US/docs/Web/JavaScript/Reference/Global_Objects/isNaN) & [isFinite](https://developer.mozilla.org/en- US/docs/Web/JavaScript/Reference/Global_Objects/isFinite) have a confusing behavior due to forced conversion to number. In ES6, [Number.isNaN](https://developer.mozilla.org/en- US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN) & [Number.isFinite](https://developer.mozilla.org/en- US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite) would fix these issues. Keep that in mind when using them.
Update : Here's how jQuery does it now (2.2-stable):
isNumeric: function(obj) {
var realStringObj = obj && obj.toString();
return !jQuery.isArray(obj) && (realStringObj - parseFloat(realStringObj) + 1) >= 0;
}
Update : Angular 4.3:
export function isNumeric(value: any): boolean {
return !isNaN(value - parseFloat(value));
}