我希望在与旧的VB6 IsNumeric()函数相同的概念空间中有什么东西?
当前回答
这是基于之前的一些回答和评论。以下内容涵盖了所有边缘情况,也相当简洁:
const isNumRegEx = /^-?(\d*\.)?\d+$/;
function isNumeric(n, allowScientificNotation = false) {
return allowScientificNotation ?
!Number.isNaN(parseFloat(n)) && Number.isFinite(n) :
isNumRegEx.test(n);
}
其他回答
这似乎抓住了看似无限数量的边缘案例:
function isNumber(x, noStr) {
/*
- Returns true if x is either a finite number type or a string containing only a number
- If empty string supplied, fall back to explicit false
- Pass true for noStr to return false when typeof x is "string", off by default
isNumber(); // false
isNumber([]); // false
isNumber([1]); // false
isNumber([1,2]); // false
isNumber(''); // false
isNumber(null); // false
isNumber({}); // false
isNumber(true); // false
isNumber('true'); // false
isNumber('false'); // false
isNumber('123asdf'); // false
isNumber('123.asdf'); // false
isNumber(undefined); // false
isNumber(Number.POSITIVE_INFINITY); // false
isNumber(Number.NEGATIVE_INFINITY); // false
isNumber('Infinity'); // false
isNumber('-Infinity'); // false
isNumber(Number.NaN); // false
isNumber(new Date('December 17, 1995 03:24:00')); // false
isNumber(0); // true
isNumber('0'); // true
isNumber(123); // true
isNumber(123.456); // true
isNumber(-123.456); // true
isNumber(-.123456); // true
isNumber('123'); // true
isNumber('123.456'); // true
isNumber('.123'); // true
isNumber(.123); // true
isNumber(Number.MAX_SAFE_INTEGER); // true
isNumber(Number.MAX_VALUE); // true
isNumber(Number.MIN_VALUE); // true
isNumber(new Number(123)); // true
*/
return (
(typeof x === 'number' || x instanceof Number || (!noStr && x && typeof x === 'string' && !isNaN(x))) &&
isFinite(x)
) || false;
};
这个问题的公认答案有很多缺陷(正如其他几位用户所强调的)。这是用javascript实现它的最简单且经过验证的方法之一:
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}
以下是一些好的测试用例:
console.log(isNumeric(12345678912345678912)); // true
console.log(isNumeric('2 ')); // true
console.log(isNumeric('-32.2 ')); // true
console.log(isNumeric(-32.2)); // true
console.log(isNumeric(undefined)); // false
// the accepted answer fails at these tests:
console.log(isNumeric('')); // false
console.log(isNumeric(null)); // false
console.log(isNumeric([])); // false
2020年10月2日:请注意,许多简单的方法都充满了微妙的错误(例如空白、隐式部分解析、基数、数组强制等),这里的许多答案都没有考虑到。以下实现可能适用于您,但请注意,它不适用于小数点“.”以外的数字分隔符:
function isNumeric(str) {
if (typeof str != "string") return false // we only process strings!
return !isNaN(str) && // use type coercion to parse the _entirety_ of the string (`parseFloat` alone does not do this)...
!isNaN(parseFloat(str)) // ...and ensure strings of whitespace fail
}
要检查变量(包括字符串)是否是数字,请检查它是否不是数字:
无论变量内容是字符串还是数字,这都是有效的。
isNaN(num) // returns true if the variable does NOT contain a valid number
示例
isNaN(123) // false
isNaN('123') // false
isNaN('1e10000') // false (This translates to Infinity, which is a number)
isNaN('foo') // true
isNaN('10px') // true
isNaN('') // false
isNaN(' ') // false
isNaN(false) // false
当然,如果需要,您可以否定这一点。例如,要实现您给出的IsNumeric示例:
function isNumeric(num){
return !isNaN(num)
}
要将包含数字的字符串转换为数字,请执行以下操作:
仅当字符串仅包含数字字符时有效,否则返回NaN。
+num // returns the numeric value of the string, or NaN
// if the string isn't purely numeric characters
示例
+'12' // 12
+'12.' // 12
+'12..' // NaN
+'.12' // 0.12
+'..12' // NaN
+'foo' // NaN
+'12px' // NaN
将字符串松散地转换为数字
用于将“12px”转换为12,例如:
parseInt(num) // extracts a numeric value from the
// start of the string, or NaN.
示例
parseInt('12') // 12
parseInt('aaa') // NaN
parseInt('12px') // 12
parseInt('foo2') // NaN These last three may
parseInt('12a5') // 12 be different from what
parseInt('0x10') // 16 you expected to see.
浮子
请记住,与+num不同,parseInt(顾名思义)将通过截断小数点后的所有内容来将浮点转换为整数(如果因为这种行为而希望使用parseInt(),那么最好使用另一种方法):
+'12.345' // 12.345
parseInt(12.345) // 12
parseInt('12.345') // 12
空字符串
空字符串可能有点违背直觉+num将空字符串或带空格的字符串转换为零,isNaN()假设相同:
+'' // 0
+' ' // 0
isNaN('') // false
isNaN(' ') // false
但parseInt()不同意:
parseInt('') // NaN
parseInt(' ') // NaN
parseInt(),但要注意,这个函数有点不同,例如,它为parseInt返回100(“100px”)。
这里是isNumber实现的高性能(2.5*10^7迭代/s@3.8GHz Haswell)版本。它适用于我能找到的每个测试用例(包括符号):
var isNumber = (function () {
var isIntegerTest = /^\d+$/;
var isDigitArray = [!0, !0, !0, !0, !0, !0, !0, !0, !0, !0];
function hasLeading0s (s) {
return !(typeof s !== 'string' ||
s.length < 2 ||
s[0] !== '0' ||
!isDigitArray[s[1]] ||
isIntegerTest.test(s));
}
var isWhiteSpaceTest = /\s/;
return function isNumber (s) {
var t = typeof s;
var n;
if (t === 'number') {
return (s <= 0) || (s > 0);
} else if (t === 'string') {
n = +s;
return !((!(n <= 0) && !(n > 0)) || n === '0' || hasLeading0s(s) || !(n !== 0 || !(s === '' || isWhiteSpaceTest.test(s))));
} else if (t === 'object') {
return !(!(s instanceof Number) || ((n = +s), !(n <= 0) && !(n > 0)));
}
return false;
};
})();