39

在一些项目中,我需要验证一些数据,并尽可能确定它是可用于数学运算的 javascript 数值。

jQuery 和其他一些 javascript 库已经包含这样的函数,通常称为 isNumeric。还有一篇关于 stackoverflow的帖子已被广泛接受为答案,与前面提到的库正在使用的通用例程相同。

function isNumber(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

作为我的第一篇文章,我无法在该线程中回复。我在接受的帖子中遇到的问题是,似乎有一些极端情况影响了我正在做的一些工作,因此我进行了一些更改以尝试解决我遇到的问题。

首先,如果参数是长度为 1 的数组,并且该单个元素是上述逻辑视为数字的类型,则上面的代码将返回 true。在我看来,如果它是一个数组,那么它就不是数字的。

为了缓解这个问题,我添加了一个检查以从逻辑中折扣数组

function isNumber(n) {
  return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n);
}

当然,你也可以使用Array.isArray代替Object.prototype.toString.call(n) !== '[object Array]'

编辑:我已更改代码以反映数组的通用测试,或者您可以使用 jquery$.isArray或原型Object.isArray

我的第二个问题是负十六进制整数文字字符串(“-0xA”-> -10)没有被算作数字。但是,正十六进制整数文字字符串(“0xA”-> 10)被视为数字。我需要两者都是有效的数字。

然后我修改了逻辑以考虑到这一点。

function isNumber(n) {
  return Object.prototype.toString.call(n) !== '[object Array]' &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}

如果您担心每次调用函数时创建正则表达式,那么您可以在闭包中重写它,就像这样

isNumber = (function () {
  var rx = /^-/;

  return function (n) {
      return Object.prototype.toString.call(n) !== '[object Array]' && !isNaN(parseFloat(n)) && isFinite(n.toString().replace(rx, ''));
  };
}());

然后我拿了 CMS +30 测试用例并在 jsfiddle 上克隆了测试,添加了我的额外测试用例和我上面描述的解决方案。

一切似乎都按预期工作,我没有遇到任何问题。您可以看到任何问题,代码或理论吗?

它可能不会取代广泛接受/使用的答案,但如果这是您所期望的 isNumeric 函数的结果,那么希望这会有所帮助。

编辑:正如Bergi所指出的,还有其他可能的对象可以被认为是数字的,白名单比黑名单更好。考虑到这一点,我将添加到标准中。

我希望我的 isNumeric 函数只考虑数字或字符串

考虑到这一点,最好使用

function isNumber(n) {
  return (Object.prototype.toString.call(n) === '[object Number]' || Object.prototype.toString.call(n) === '[object String]') &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}

这已添加为测试 22

4

7 回答 7

4

在我看来,如果它是一个数组,那么它就不是数字的。为了缓解这个问题,我添加了一个检查以从逻辑中折扣数组

您也可以在任何其他对象上遇到这个问题,例如{toString:function(){return "1.2";}}. 你认为哪些对象是数字的?Number对象?没有任何?

与其尝试将某些未通过测试的事物列入黑名单,不如将您希望成为数字的事物明确列入白名单。你的函数应该得到什么,原始字符串和数字?然后准确地测试它们:

(typeof n == "string" || typeof n == "number")
于 2013-03-05T17:36:38.163 回答
1

如果您可以使用正则表达式,这可能会奏效:

function (n) 
    { 
    return (Object.prototype.toString.call(n) === '[object Number]' ||
            Object.prototype.toString.call(n) === '[object String]') && 
           (typeof(n) != 'undefined')  &&  (n!=null) && 
           (/^-?\d+((.\d)?\d*(e[-]?\d)?(\d)*)$/.test(n.toString()) ||
           /^-?0x[0-9A-F]+$/.test(n.toString()));
    }

编辑: 修复了十六进制数字的问题

于 2013-03-07T13:54:03.520 回答
0
function isNumber(value){
    return !isNaN(parseFloat(value)) && 
        isFinite(value.toString().replace(/^-/, '')) && 
        typeof value !== 'object';

}

或者 :

function isNumber(value){
    return !Array.isArray(value) && !isNaN(parseFloat(value)) && 
        isFinite(value.toString().replace(/^-/, '')) && 
        Object.prototype.toString.call(value) !== '[object Object]';
}
于 2013-03-10T01:18:29.970 回答
0

isNaN 函数用于检查值是否为数字。如果值是数字,则返回 true,否则返回 false。

代码:

 <script>

         function IsNumeric(val) {

              if (isNaN(parseFloat(val))) {

                 return false;

          }

          return true

  }


  bool IsNumeric(string);


</script>
于 2013-03-09T13:02:52.103 回答
0

怎么样:

function isNumber(value) {
  value = Number(value);
  return typeof value === 'number' && !isNaN(value) && isFinite(value);
}
于 2013-03-05T00:01:41.090 回答
0
function isNumber(value){return typeof value == 'number';}
于 2013-02-27T02:02:33.617 回答
0

如果 AMD 听起来不错,请查看mout 的 isNumber()

于 2013-02-27T23:47:32.953 回答