How to check if a JavaScript number is a real, valid number?

后端 未结 6 1514
礼貌的吻别
礼貌的吻别 2020-12-16 15:30

MY code is:

function isNumber(n){
return typeof n == \'number\' && !isNaN(n);
}

window.onload=function(){
var a=0,b=1,c=2.2,d=-3,e=-4.4,f=10/3;
var          


        
相关标签:
6条回答
  • 2020-12-16 15:47

    It depends on what you wish to regard as a number. Your code classifies Infinity and -Infinity as numbers. If you don’t want that, replace !isNaN(n) by isFinite(n).

    And your code classifies '42' (a string literal) as not being a number, due to the type check; but I supposed that’s intentional.

    0 讨论(0)
  • 2020-12-16 15:53

    JS numbers can be among the following values:

    • Finite numbers
    • +Infinity and -Infinity
    • NaN

    Then there also non-number values which are coercible to numbers, e.g. number objects. You might want to consider them numerical.

    If you only want to test finite numbers, simply use Number.isFinite:

    Number.isFinite(value)
    

    var isNumber = Number.isFinite;
    assert('isNumber(1)', true);
    assert('isNumber(1.1)', true);
    assert('isNumber(+0)', true);
    assert('isNumber(-0)', true);
    assert('isNumber(-1.1)', true);
    assert('isNumber(Math.PI)', true);
    assert('isNumber(1e300)', true);
    assert('isNumber(+Infinity)', false);
    assert('isNumber(-Infinity)', false);
    assert('isNumber(NaN)', false);
    assert('isNumber(null)', false);
    assert('isNumber(undefined)', false);
    assert('isNumber(true)', false);
    assert('isNumber(false)', false);
    assert('isNumber("123")', false);
    assert('isNumber("foo")', false);
    assert('isNumber(new Number(1))', false);
    assert('isNumber([])', false);
    assert('isNumber({})', false);
    assert('isNumber(function(){})', false);
    function assert(code, expected) {
      var result = eval(code);
      console.log('Test ' + (result===expected ? 'pass' : 'FAIL') + ': ', code, ' -> ', result);
    }

    If you want to include infinities, check the type and exclude NaN:

    typeof value === "number" && !Number.isNaN(value)
    

    function isNumber(value) {
      return typeof value === "number" && !Number.isNaN(value);
    }
    assert('isNumber(1)', true);
    assert('isNumber(1.1)', true);
    assert('isNumber(+0)', true);
    assert('isNumber(-0)', true);
    assert('isNumber(-1.1)', true);
    assert('isNumber(Math.PI)', true);
    assert('isNumber(1e300)', true);
    assert('isNumber(+Infinity)', true);
    assert('isNumber(-Infinity)', true);
    assert('isNumber(NaN)', false);
    assert('isNumber(null)', false);
    assert('isNumber(undefined)', false);
    assert('isNumber(true)', false);
    assert('isNumber(false)', false);
    assert('isNumber("123")', false);
    assert('isNumber("foo")', false);
    assert('isNumber(new Number(1))', false);
    assert('isNumber([])', false);
    assert('isNumber({})', false);
    assert('isNumber(function(){})', false);
    function assert(code, expected) {
      var result = eval(code);
      console.log('Test ' + (result===expected ? 'pass' : 'FAIL') + ': ', code, ' -> ', result);
    }

    If you want to consider number objects as numbers, you can unwrap them using

    value = Number.valueOf.call(value); // throws if value was not a number object
    

    function isNumber(value) {
      try { value = Number.prototype.valueOf.call(value); } catch(err) { }
      return Number.isFinite(value);
    }
    assert('isNumber(1)', true);
    assert('isNumber(1.1)', true);
    assert('isNumber(+0)', true);
    assert('isNumber(-0)', true);
    assert('isNumber(-1.1)', true);
    assert('isNumber(Math.PI)', true);
    assert('isNumber(1e300)', true);
    assert('isNumber(+Infinity)', false);
    assert('isNumber(-Infinity)', false);
    assert('isNumber(NaN)', false);
    assert('isNumber(null)', false);
    assert('isNumber(undefined)', false);
    assert('isNumber(true)', false);
    assert('isNumber(false)', false);
    assert('isNumber("123")', false);
    assert('isNumber("foo")', false);
    assert('isNumber(new Number(1))', true);
    assert('isNumber([])', false);
    assert('isNumber({})', false);
    assert('isNumber(function(){})', false);
    function assert(code, expected) {
      var result = eval(code);
      console.log('Test ' + (result===expected ? 'pass' : 'FAIL') + ': ', code, ' -> ', result);
    }

    If you want to include arbitrary values coercible to numbers, you can use the unary + to coerce.

    value = +value; // throws if value was not number-coercible
    

    There is also the isNaN function (not to be confused with Number.isNaN), which will first coerce and then compare with NaN. But be aware whitespace strings and null are coerced to +0, not NaN. So you might be interested in Validate decimal numbers in JavaScript - IsNumeric()

    0 讨论(0)
  • 2020-12-16 15:56

    If you want to check whether a number is a real number, you should also check whether it's finite:

    function isNumber(n){
        return typeof n == 'number' && !isNaN(n) && isFinite(n);
     }
    

    Another method (explanation below):

    function isNumber(n){
        return typeof n == 'number' && !isNaN(n - n);
    }
    

    Update: Two expressions to validate a real number

    Since JavaScript numbers are representing real numbers, the substraction operand on the same number should produce the zero value (additive identity). Numbers out of range should (and will) be invalid, NaN.

    1        - 1        = 0    // OK
    Infinity - Infinity = NaN  // Expected
    NaN      - NaN      = NaN  // Expected
    NaN      - Infinity = NaN
    
    0 讨论(0)
  • 2020-12-16 16:01

    I use combination of parse and check for numbers.. as outlined below

    function isNumber(inputValue){ return ((parseFloat(inputValue) ==0 || parseFloat(inputValue)) && !isNaN(inputValue)); };

    hope this helps

    0 讨论(0)
  • 2020-12-16 16:01

    For react or other framework users, possible solution could be:

    const { onChange, value } = this.props;
    return (
      <input
        type="text" // Note: I have kept this as text
        value={typeof value !== 'number' || isNaN(value) ? '' : value}
        className={classnames('input')}
        onChange={(event) =>
          onChange &&
          onChange(parseFloat(event.target.value))
        }
      />)
    

    This works on safari as well.

    Thanks.

    0 讨论(0)
  • 2020-12-16 16:06

    If you consider a number in its object wrapper to be a number, then it will fail with:

    isNumber( new Number(123) )
    

    Since a downvoter is having some comprehension troubles that couldn't be alleviated by a simple test, new Number(123) will return 'object' from the typeof test, and as such will not pass.

    0 讨论(0)
提交回复
热议问题