(Built-in) way in JavaScript to check if a string is a valid number

前端 未结 30 3382
-上瘾入骨i
-上瘾入骨i 2020-11-22 01:54

I\'m hoping there\'s something in the same conceptual space as the old VB6 IsNumeric() function?

相关标签:
30条回答
  • 2020-11-22 02:17

    You can use the result of Number when passing an argument to its constructor.

    If the argument (a string) cannot be converted into a number, it returns NaN, so you can determinate if the string provided was a valid number or not.

    Notes: Note when passing empty string or '\t\t' and '\n\t' as Number will return 0; Passing true will return 1 and false returns 0.

        Number('34.00') // 34
        Number('-34') // -34
        Number('123e5') // 12300000
        Number('123e-5') // 0.00123
        Number('999999999999') // 999999999999
        Number('9999999999999999') // 10000000000000000 (integer accuracy up to 15 digit)
        Number('0xFF') // 255
        Number('Infinity') // Infinity  
    
        Number('34px') // NaN
        Number('xyz') // NaN
        Number('true') // NaN
        Number('false') // NaN
    
        // cavets
        Number('    ') // 0
        Number('\t\t') // 0
        Number('\n\t') // 0
    
    0 讨论(0)
  • 2020-11-22 02:17

    I recently wrote an article about ways to ensure a variable is a valid number: https://github.com/jehugaleahsa/artifacts/blob/master/2018/typescript_num_hack.md The article explains how to ensure floating point or integer, if that's important (+x vs ~~x).

    The article assumes the variable is a string or a number to begin with and trim is available/polyfilled. It wouldn't be hard to extend it to handle other types, as well. Here's the meat of it:

    // Check for a valid float
    if (x == null
        || ("" + x).trim() === ""
        || isNaN(+x)) {
        return false;  // not a float
    }
    
    // Check for a valid integer
    if (x == null
        || ("" + x).trim() === ""
        || ~~x !== +x) {
        return false;  // not an integer
    }
    
    0 讨论(0)
  • 2020-11-22 02:18

    This appears to catch the seemingly infinite number of edge cases:

    function isNumber(x, noStr) {
        /*
    
            - Returns true if x is either a finite number type or a string containing only a number
            - If empty string supplied, fall back to explicit false
            - Pass true for noStr to return false when typeof x is "string", off by default
    
            isNumber(); // false
            isNumber([]); // false
            isNumber([1]); // false
            isNumber([1,2]); // false
            isNumber(''); // false
            isNumber(null); // false
            isNumber({}); // false
            isNumber(true); // false
            isNumber('true'); // false
            isNumber('false'); // false
            isNumber('123asdf'); // false
            isNumber('123.asdf'); // false
            isNumber(undefined); // false
            isNumber(Number.POSITIVE_INFINITY); // false
            isNumber(Number.NEGATIVE_INFINITY); // false
            isNumber('Infinity'); // false
            isNumber('-Infinity'); // false
            isNumber(Number.NaN); // false
            isNumber(new Date('December 17, 1995 03:24:00')); // false
            isNumber(0); // true
            isNumber('0'); // true
            isNumber(123); // true
            isNumber(123.456); // true
            isNumber(-123.456); // true
            isNumber(-.123456); // true
            isNumber('123'); // true
            isNumber('123.456'); // true
            isNumber('.123'); // true
            isNumber(.123); // true
            isNumber(Number.MAX_SAFE_INTEGER); // true
            isNumber(Number.MAX_VALUE); // true
            isNumber(Number.MIN_VALUE); // true
            isNumber(new Number(123)); // true
        */
    
        return (
            (typeof x === 'number' || x instanceof Number || (!noStr && x && typeof x === 'string' && !isNaN(x))) &&
            isFinite(x)
        ) || false;
    };
    
    0 讨论(0)
  • 2020-11-22 02:18

    I used this function as a form validation tool, and I didn't want users to be able to write exponential function, so I came up with this function:

    <script>
    
        function isNumber(value, acceptScientificNotation) {
    
            if(true !== acceptScientificNotation){
                return /^-{0,1}\d+(\.\d+)?$/.test(value);
            }
    
            if (true === Array.isArray(value)) {
                return false;
            }
            return !isNaN(parseInt(value, 10));
        }
    
    
        console.log(isNumber(""));              // false
        console.log(isNumber(false));           // false
        console.log(isNumber(true));            // false
        console.log(isNumber("0"));             // true
        console.log(isNumber("0.1"));           // true
        console.log(isNumber("12"));            // true
        console.log(isNumber("-12"));           // true
        console.log(isNumber(-45));             // true
        console.log(isNumber({jo: "pi"}));      // false
        console.log(isNumber([]));              // false
        console.log(isNumber([78, 79]));        // false
        console.log(isNumber(NaN));             // false
        console.log(isNumber(Infinity));        // false
        console.log(isNumber(undefined));       // false
        console.log(isNumber("0,1"));           // false
    
    
    
        console.log(isNumber("1e-1"));          // false
        console.log(isNumber("1e-1", true));    // true
    </script>
    
    0 讨论(0)
  • 2020-11-22 02:20

    parseInt(), but be aware that this function is a bit different in the sense that it for example returns 100 for parseInt("100px").

    0 讨论(0)
  • 2020-11-22 02:21

    Old question, but there are several points missing in the given answers.

    Scientific notation.

    !isNaN('1e+30') is true, however in most of the cases when people ask for numbers, they do not want to match things like 1e+30.

    Large floating numbers may behave weird

    Observe (using Node.js):

    > var s = Array(16 + 1).join('9')
    undefined
    > s.length
    16
    > s
    '9999999999999999'
    > !isNaN(s)
    true
    > Number(s)
    10000000000000000
    > String(Number(s)) === s
    false
    >
    

    On the other hand:

    > var s = Array(16 + 1).join('1')
    undefined
    > String(Number(s)) === s
    true
    > var s = Array(15 + 1).join('9')
    undefined
    > String(Number(s)) === s
    true
    >
    

    So, if one expects String(Number(s)) === s, then better limit your strings to 15 digits at most (after omitting leading zeros).

    Infinity

    > typeof Infinity
    'number'
    > !isNaN('Infinity')
    true
    > isFinite('Infinity')
    false
    >
    

    Given all that, checking that the given string is a number satisfying all of the following:

    • non scientific notation
    • predictable conversion to Number and back to String
    • finite

    is not such an easy task. Here is a simple version:

      function isNonScientificNumberString(o) {
        if (!o || typeof o !== 'string') {
          // Should not be given anything but strings.
          return false;
        }
        return o.length <= 15 && o.indexOf('e+') < 0 && o.indexOf('E+') < 0 && !isNaN(o) && isFinite(o);
      }
    

    However, even this one is far from complete. Leading zeros are not handled here, but they do screw the length test.

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