我希望在与旧的VB6 IsNumeric()函数相同的概念空间中有什么东西?


当前回答

这里有一个优雅的单行线来检查sNum是否是有效的数值。该代码也已针对各种输入进行了测试。

// returns True if sNum is a numeric value    
!!sNum && !isNaN(+sNum.replace(/\s|\$/g, ''));  

向@gman提示错误。

其他回答

尝试isNan函数:

isNaN()函数确定值是否为非法数字(Not-a-number)。如果值等于NaN,则此函数返回true。否则返回false。此函数与特定于Number的Number.isNaN()方法不同。全局isNaN()函数将测试值转换为Number,然后对其进行测试。Number.isNan()不会将值转换为Number,并且对于任何非Number类型的值都不会返回true。。。

如果有人对此感到失望的话,我花了一些时间来修补moment.js(https://github.com/moment/moment). 我从中得到了一些东西:

function isNumeric(val) {
    var _val = +val;
    return (val !== val + 1) //infinity check
        && (_val === +val) //Cute coercion check
        && (typeof val !== 'object') //Array/object check
}

处理以下情况:

真!:

isNumeric("1"))
isNumeric(1e10))
isNumeric(1E10))
isNumeric(+"6e4"))
isNumeric("1.2222"))
isNumeric("-1.2222"))
isNumeric("-1.222200000000000000"))
isNumeric("1.222200000000000000"))
isNumeric(1))
isNumeric(0))
isNumeric(-0))
isNumeric(1010010293029))
isNumeric(1.100393830000))
isNumeric(Math.LN2))
isNumeric(Math.PI))
isNumeric(5e10))

错误!:

isNumeric(NaN))
isNumeric(Infinity))
isNumeric(-Infinity))
isNumeric())
isNumeric(undefined))
isNumeric('[1,2,3]'))
isNumeric({a:1,b:2}))
isNumeric(null))
isNumeric([1]))
isNumeric(new Date()))

具有讽刺意味的是,我最纠结的是:

isNumeric(new Number(1)) => false

欢迎提出任何建议。:]

老问题,但给出的答案中缺少几点。

科学记数法。

!isNaN('e+30')是正确的,但在大多数情况下,当人们要求数字时,他们不想匹配像1e+30这样的数字。

大浮点数的行为可能很奇怪

观察(使用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
>

另一方面:

> 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
>

因此,如果期望String(Number(s))==s,那么最好将字符串限制在最多15位(省略前导零后)。

无穷

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

考虑到所有这些,检查给定字符串是否为满足以下所有条件的数字:

非科学记数法可预测地转换为数字并返回到字符串有限的

这不是一项容易的任务。下面是一个简单的版本:

  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);
  }

然而,即使是这一点也远未完成。这里不处理前导零,但它们确实会破坏长度测试。

为什么jQuery的实现不够好?

function isNumeric(a) {
    var b = a && a.toString();
    return !$.isArray(a) && b - parseFloat(b) + 1 >= 0;
};

Michael提出了类似的建议(尽管我在这里窃取了“user1691651-John”的修改版本):

function isNumeric(num){
    num = "" + num; //coerce num to be a string
    return !isNaN(num) && !isNaN(parseFloat(num));
}

以下是一个解决方案,性能很可能很差,但结果很好。这是一个由jQuery 1.12.4实现和Michael的答案组成的装置,并对前导/尾随空格进行了额外检查(因为Michael的版本对带有前导/尾随空间的数字返回true):

function isNumeric(a) {
    var str = a + "";
    var b = a && a.toString();
    return !$.isArray(a) && b - parseFloat(b) + 1 >= 0 &&
           !/^\s+|\s+$/g.test(str) &&
           !isNaN(str) && !isNaN(parseFloat(str));
};

不过,后一个版本有两个新变量。你可以通过以下方式绕过其中一个:

function isNumeric(a) {
    if ($.isArray(a)) return false;
    var b = a && a.toString();
    a = a + "";
    return b - parseFloat(b) + 1 >= 0 &&
            !/^\s+|\s+$/g.test(a) &&
            !isNaN(a) && !isNaN(parseFloat(a));
};

除了手动测试我将要遇到的几个用例之外,我还没有对这些用例进行过很多测试,这都是非常标准的东西。这是一种“站在巨人的肩膀上”的情况。

如果你喜欢一种巧妙的方式,并且你喜欢让同事感到困惑,你可以使用:

const isNumeric = str => parseFloat(str) === parseFloat(str)

证明:

const isNumeric=str=>parseFloat(str)===parseFloit(str)console.log(isNumeric(“10”))console.log(isNumeric('-10.2'))console.log(isNumeric('15abc'))console.log(isNumeric('0.0001'))console.log(isNumeric('abc'))console.log(isNumeric('abc123'))