我希望在与旧的VB6 IsNumeric()函数相同的概念空间中有什么东西?
当前回答
如果您真的想确保字符串只包含一个数字、任何数字(整数或浮点)以及一个数字,则不能使用parseInt()/parseFloat()、number()或!isNaN()。注意!isNaN()实际上在Number()返回一个数字时返回true,在返回NaN时返回false,因此我将从后面的讨论中排除它。
parseFloat()的问题是,如果字符串包含任何数字,它将返回一个数字,即使字符串不只包含一个数字:
parseFloat("2016-12-31") // returns 2016
parseFloat("1-1") // return 1
parseFloat("1.2.3") // returns 1.2
Number()的问题是,在传递的值根本不是数字的情况下,它将返回一个数字!
Number("") // returns 0
Number(" ") // returns 0
Number(" \u00A0 \t\n\r") // returns 0
滚动自己的正则表达式的问题是,除非您创建了与Javascript识别的浮点数匹配的精确正则表达式,否则您将错过案例或识别不应该出现的案例。即使您可以滚动自己的正则表达式,为什么?有更简单的内置方法来实现。
然而,事实证明,Number()(和isNaN())在parseFloat()不应该返回数字的情况下都做了正确的事情,反之亦然。因此,要确定字符串是否真的是一个数字,请调用这两个函数,看看它们是否都返回true:
function isNumber(str) {
if (typeof str != "string") return false // we only process strings!
// could also coerce to string: str = ""+str
return !isNaN(str) && !isNaN(parseFloat(str))
}
其他回答
为什么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));
};
除了手动测试我将要遇到的几个用例之外,我还没有对这些用例进行过很多测试,这都是非常标准的东西。这是一种“站在巨人的肩膀上”的情况。
有些人也可能从基于正则表达式的答案中受益。这里是:
一行是Integer:
const isInteger = num => /^-?[0-9]+$/.test(num+'');
一行是Numeric:接受整数和小数
const isNumeric = num => /^-?[0-9]+(?:\.[0-9]+)?$/.test(num+'');
我已经测试过了,迈克尔的解决方案是最好的。投票支持上面的答案(在这个页面上搜索“如果你真的想确保有一个字符串”来找到它)。本质上,他的答案是:
function isNumeric(num){
num = "" + num; //coerce num to be a string
return !isNaN(num) && !isNaN(parseFloat(num));
}
它适用于每个测试用例,我在这里记录了这些测试用例:https://jsfiddle.net/wggehvp9/5/
许多其他解决方案在这些边缘情况下失败:“”、null、“”、true和[]。理论上,您可以使用它们,并进行适当的错误处理,例如:
return !isNaN(num);
or
return (+num === +num);
具有特殊处理/\s/,null,“”,true,false,[](和其他?)
它对TypeScript无效,因为:
声明函数isNaN(数字:数字):布尔值;
对于TypeScript,您可以使用:
/^\d+$/.测试(键)
这是基于之前的一些回答和评论。以下内容涵盖了所有边缘情况,也相当简洁:
const isNumRegEx = /^-?(\d*\.)?\d+$/;
function isNumeric(n, allowScientificNotation = false) {
return allowScientificNotation ?
!Number.isNaN(parseFloat(n)) && Number.isFinite(n) :
isNumRegEx.test(n);
}