Validate decimal numbers in JavaScript - IsNumeric

2018-12-30 23:29发布

What's the cleanest, most effective way to validate decimal numbers in JavaScript?

Bonus points for:

  1. Clarity. Solution should be clean and simple.
  2. 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

30条回答
君临天下
2楼-- · 2018-12-31 00:07

This should work. Some of the functions provided here are flawed, also should be faster than any other function here.

        function isNumeric(n)
        {
            var n2 = n;
            n = parseFloat(n);
            return (n!='NaN' && n2==n);
        }

Explained:

Create a copy of itself, then converts the number into float, then compares itself with the original number, if it is still a number, (whether integer or float) , and matches the original number, that means, it is indeed a number.

It works with numeric strings as well as plain numbers. Does not work with hexadecimal numbers.

Warning: use at your own risk, no guarantees.

查看更多
裙下三千臣
3楼-- · 2018-12-31 00:08

It can be done without RegExp as

function IsNumeric(data){
    return parseFloat(data)==data;
}
查看更多
素衣白纱
4楼-- · 2018-12-31 00:08
function inNumeric(n){
   return Number(n).toString() === n;
}

If n is numeric Number(n) will return the numeric value and toString() will turn it back to a string. But if n isn't numeric Number(n) will return NaN so it won't match the original n

查看更多
荒废的爱情
5楼-- · 2018-12-31 00:09

You can minimize this function in a lot of way, and you can also implement it with a custom regex for negative values or custom charts:

$('.number').on('input',function(){
    var n=$(this).val().replace(/ /g,'').replace(/\D/g,'');
    if (!$.isNumeric(n))
        $(this).val(n.slice(0, -1))
    else
        $(this).val(n)
});
查看更多
还给你的自由
6楼-- · 2018-12-31 00:10

I'm using simpler solution:

function isNumber(num) {
    return parseFloat(num).toString() == num
}
查看更多
后来的你喜欢了谁
7楼-- · 2018-12-31 00:10

I realize this has been answered many times, but the following is a decent candidate which can be useful in some scenarios.

it should be noted that it assumes that '.42' is NOT a number, and '4.' is NOT a number, so this should be taken into account.

function isDecimal(x) {
  return '' + x === '' + +x;
}

function isInteger(x) {
  return '' + x === '' + parseInt(x);
}

The isDecimal passes the following test:

function testIsNumber(f) {
  return f('-1') && f('-1.5') && f('0') && f('0.42')
    && !f('.42') && !f('99,999') && !f('0x89f')
    && !f('#abcdef') && !f('1.2.3') && !f('') && !f('blah');
}

The idea here is that every number or integer has one "canonical" string representation, and every non-canonical representation should be rejected. So we cast to a number and back, and see if the result is the original string.

Whether these functions are useful for you depends on the use case. One feature is that distinct strings represent distinct numbers (if both pass the isNumber() test).

This is relevant e.g. for numbers as object property names.

var obj = {};
obj['4'] = 'canonical 4';
obj['04'] = 'alias of 4';
obj[4];  // prints 'canonical 4' to the console.
查看更多
登录 后发表回答