在 JavaScript 中验证十进制数字 - IsNumeric()

新手上路,请多包涵

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

奖励积分:

  1. 明晰。解决方案应该干净简单。

  2. 跨平台。

测试用例:

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

原文由 Michael Haren 发布,翻译遵循 CC BY-SA 3.0 许可协议

阅读 1.1k
2 个回答

@Joel 的答案 非常接近,但在以下情况下会失败:

 // Whitespace strings:
 IsNumeric(' ') == true;
 IsNumeric('\t\t') == true;
 IsNumeric('\n\r') == true;

 // Number literals:
 IsNumeric(-1) == false;
 IsNumeric(0) == false;
 IsNumeric(1.1) == false;
 IsNumeric(8e5) == false;

前段时间我必须实现一个 IsNumeric 函数,以找出一个变量是否包含数值, 无论其类型如何,它都可能是一个包含数值的 String (我还必须考虑指数符号等),一个 Number 对象,几乎任何东西都可以传递给该函数,我无法做出任何类型假设,需要处理类型强制(例如 +true == 1;true 不应被视为 "numeric" )。

我认为值得分享对众多功能实现进行的这组 +30 单元测试,并分享通过我所有测试的单元测试:

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

由于强制转换为数字, PS isNaNisFinite 具有令人困惑的行为。在 ES6 中, Number.isNaNNumber.isFinite 将解决这些问题。使用它们时请记住这一点。


更新

这是 jQuery 现在的做法(2.2-stable)

 isNumeric: function(obj) {
 var realStringObj = obj && obj.toString();
 return !jQuery.isArray(obj) && (realStringObj - parseFloat(realStringObj) + 1) >= 0;
 }

更新

角 4.3

 export function isNumeric(value: any): boolean {
 return !isNaN(value - parseFloat(value));
 }

原文由 Christian C. Salvadó 发布,翻译遵循 CC BY-SA 4.0 许可协议

啊!不要听正则表达式的答案。 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()。

原文由 Joel Coehoorn 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题