在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

当前回答

无需使用额外的库。

const IsNumeric = (...numbers) => {
  return numbers.reduce((pre, cur) => pre && !!(cur === 0 || +cur), true);
};

Test

> IsNumeric(1)
true
> IsNumeric(1,2,3)
true
> IsNumeric(1,2,3,0)
true
> IsNumeric(1,2,3,0,'')
false
> IsNumeric(1,2,3,0,'2')
true
> IsNumeric(1,2,3,0,'200')
true
> IsNumeric(1,2,3,0,'-200')
true
> IsNumeric(1,2,3,0,'-200','.32')
true

其他回答

啊!不要听正则表达式的答案。RegEx很讨厌这个,我说的不仅仅是性能。用正则表达式很容易发现细微的、不可能发现的错误。

如果您不能使用isNaN(),这应该会更好:

function IsNumeric(input)
{
    return (input - 0) == input && (''+input).trim().length > 0;
}

以下是它的工作原理:

(input-0)表达式强制JavaScript对输入值执行类型强制;它必须首先被解释为减法运算的数字。如果转换为数字失败,表达式将生成NaN。然后将此数字结果与传入的原始值进行比较。由于左侧现在是数字,因此再次使用类型强制。既然来自双方的输入被强制为来自相同原始值的相同类型,那么您会认为它们应该总是相同的(总是正确的)。然而,有一条特殊规则规定NaN永远不等于NaN,因此不能转换为数字的值(只有不能转换为数值的值)将导致错误。

长度检查用于涉及空字符串的特殊情况。还要注意,这取决于0x89f测试,但这是因为在许多环境中,这是定义数字文字的好方法。如果您想捕捉特定场景,可以添加额外的检查。更好的是,如果这是您不使用isNaN()的原因,那么只需将您自己的函数包装在isNaN)周围,这也可以进行额外的检查。

总之,如果您想知道某个值是否可以转换为数字,请尝试将其转换为数字。


我回去研究了为什么空白字符串没有预期的输出,我想我现在明白了:空字符串被强制为0而不是NaN。只需在长度检查之前修剪字符串即可处理这种情况。

针对新代码运行单元测试,它只会在无穷大和布尔文本上失败,唯一可能出现问题的是,如果你正在生成代码(真的,谁会键入文本并检查它是否为数字?你应该知道),那将是一些奇怪的代码。

但是,再次强调,使用此选项的唯一原因是,如果出于某种原因,您必须避免使用isNaN()。

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

isNumeric=(el)=>{return Boolean(parseFloat(el))&&isFinite(el)}

没有什么不同,但我们可以使用布尔构造函数

这里有一个非常简单的(在Chrome、Firefox和IE中测试):

function isNumeric(x) {
  return parseFloat(x) == x;
}

来自问题的测试用例:

console.log('trues');
console.log(isNumeric('-1'));
console.log(isNumeric('-1.5'));
console.log(isNumeric('0'));
console.log(isNumeric('0.42'));
console.log(isNumeric('.42'));

console.log('falses');
console.log(isNumeric('99,999'));
console.log(isNumeric('0x89f'));
console.log(isNumeric('#abcdef'));
console.log(isNumeric('1.2.3'));
console.log(isNumeric(''));
console.log(isNumeric('blah'));

更多测试用例:

console.log('trues');
console.log(isNumeric(0));
console.log(isNumeric(-1));
console.log(isNumeric(-500));
console.log(isNumeric(15000));
console.log(isNumeric(0.35));
console.log(isNumeric(-10.35));
console.log(isNumeric(2.534e25));
console.log(isNumeric('2.534e25'));
console.log(isNumeric('52334'));
console.log(isNumeric('-234'));
console.log(isNumeric(Infinity));
console.log(isNumeric(-Infinity));
console.log(isNumeric('Infinity'));
console.log(isNumeric('-Infinity'));

console.log('falses');
console.log(isNumeric(NaN));
console.log(isNumeric({}));
console.log(isNumeric([]));
console.log(isNumeric(''));
console.log(isNumeric('one'));
console.log(isNumeric(true));
console.log(isNumeric(false));
console.log(isNumeric());
console.log(isNumeric(undefined));
console.log(isNumeric(null));
console.log(isNumeric('-234aa'));

注意,它认为无穷大是一个数。

检查变量是否包含有效数字只是一个看起来像数字的字符串,可以使用Number.isFinite(值)。

这是语言的一部分,因为2015年

示例:

Number.isFinite(Infinity)   // false
Number.isFinite(NaN)        // false
Number.isFinite(-Infinity)  // false

Number.isFinite(0)          // true
Number.isFinite(2e64)       // true

Number.isFinite('0')        // false
Number.isFinite(null)       // false