在JavaScript中验证十进制数字最干净、最有效的方法是什么?

奖励积分:

清晰解决方案应干净简单。跨平台。

测试用例:

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

当前回答

可以使用类型检查库,如https://github.com/arasatasaygin/is.js或者从那里提取一个检查片段(https://github.com/arasatasaygin/is.js/blob/master/is.js#L131):

is.nan = function(value) {    // NaN is number :) 
  return value !== value;
};
 // is a given value number?
is.number = function(value) {
    return !is.nan(value) && Object.prototype.toString.call(value) === '[object Number]';
};

通常,如果您需要它来验证参数类型(在函数调用的入口点),您可以使用符合JSDOC的契约(https://www.npmjs.com/package/bycontract):

/**
 * This is JSDOC syntax
 * @param {number|string} sum
 * @param {Object.<string, string>} payload
 * @param {function} cb
 */
function foo( sum, payload, cb ) {
  // Test if the contract is respected at entry point
  byContract( arguments, [ "number|string", "Object.<string, string>", "function" ] );
}
// Test it
foo( 100, { foo: "foo" }, function(){}); // ok
foo( 100, { foo: 100 }, function(){}); // exception

其他回答

可以使用类型检查库,如https://github.com/arasatasaygin/is.js或者从那里提取一个检查片段(https://github.com/arasatasaygin/is.js/blob/master/is.js#L131):

is.nan = function(value) {    // NaN is number :) 
  return value !== value;
};
 // is a given value number?
is.number = function(value) {
    return !is.nan(value) && Object.prototype.toString.call(value) === '[object Number]';
};

通常,如果您需要它来验证参数类型(在函数调用的入口点),您可以使用符合JSDOC的契约(https://www.npmjs.com/package/bycontract):

/**
 * This is JSDOC syntax
 * @param {number|string} sum
 * @param {Object.<string, string>} payload
 * @param {function} cb
 */
function foo( sum, payload, cb ) {
  // Test if the contract is respected at entry point
  byContract( arguments, [ "number|string", "Object.<string, string>", "function" ] );
}
// Test it
foo( 100, { foo: "foo" }, function(){}); // ok
foo( 100, { foo: 100 }, function(){}); // exception

我意识到最初的问题没有提到jQuery,但如果您确实使用jQuery,您可以这样做:

$.isNumeric(val)

易于理解的

https://api.jquery.com/jQuery.isNumeric/(截至jQuery 1.7)

使用函数isNaN。我相信如果你测试!是NaN(你的字符串),它适用于任何这些情况。

如果我没有弄错,这应该匹配任何有效的JavaScript数值,不包括常量(Infinity,NaN)和符号运算符+/-(因为就我而言,它们实际上不是数字的一部分,它们是独立的运算符):

我需要一个令牌化器,将数字发送到JavaScript进行评估不是一个选项。。。它肯定不是最短的正则表达式,但我相信它抓住了JavaScript数字语法的所有细微之处。

/^(?:(?:(?:[1-9]\d*|\d)\.\d*|(?:[1-9]\d*|\d)?\.\d+|(?:[1-9]\d*|\d)) 
(?:[e]\d+)?|0[0-7]+|0x[0-9a-f]+)$/i

有效数字包括:

 - 0
 - 00
 - 01
 - 10
 - 0e1
 - 0e01
 - .0
 - 0.
 - .0e1
 - 0.e1
 - 0.e00
 - 0xf
 - 0Xf

无效数字将为

 - 00e1
 - 01e1
 - 00.0
 - 00x0
 - .
 - .e0

我对@CMS的答案唯一的问题是排除了NaN和Infinity,这两个数字在很多情况下都很有用。检查NaN的一种方法是检查自身不相等的数值,NaN!=不!所以,你真的有3个测试要处理。。。

function isNumber(n) {
  n = parseFloat(n);
  return !isNaN(n) || n != n;
}
function isFiniteNumber(n) {
  n = parseFloat(n);
  return !isNaN(n) && isFinite(n);
}    
function isComparableNumber(n) {
  n = parseFloat(n);
  return (n >=0 || n < 0);
}

isFiniteNumber('NaN')
false
isFiniteNumber('OxFF')
true
isNumber('NaN')
true
isNumber(1/0-1/0)
true
isComparableNumber('NaN')
false
isComparableNumber('Infinity')
true

我的isComparableNumber与另一个优雅的答案非常接近,但它处理十六进制和其他数字的字符串表示。