我希望在与旧的VB6 IsNumeric()函数相同的概念空间中有什么东西?
当前回答
我最近写了一篇关于如何确保变量是有效数字的文章:https://github.com/jehugaleahsa/artifacts/blob/master/2018/typescript_num_hack.md本文解释了如何确保浮点或整数,如果这很重要(+x vs ~~x)。
本文假设变量是一个字符串或一个数字开头,trim可用/polyfulled。将其扩展到处理其他类型也不难。这是它的肉:
// Check for a valid float
if (x == null
|| ("" + x).trim() === ""
|| isNaN(+x)) {
return false; // not a float
}
// Check for a valid integer
if (x == null
|| ("" + x).trim() === ""
|| ~~x !== +x) {
return false; // not an integer
}
其他回答
typeof运算符返回一个字符串,指示操作数值的类型。
对于number,它返回“number”字符串。
function isNumber(num) {
return typeof num === "number";
}
您可以使用类型(如流库)来进行静态编译时检查。当然,对于用户输入并不是很有用。
// @flow
function acceptsNumber(value: number) {
// ...
}
acceptsNumber(42); // Works!
acceptsNumber(3.14); // Works!
acceptsNumber(NaN); // Works!
acceptsNumber(Infinity); // Works!
acceptsNumber("foo"); // Error!
防止空字符串和null时
// Base cases that are handled properly
Number.isNaN(Number('1')); // => false
Number.isNaN(Number('-1')); // => false
Number.isNaN(Number('1.1')); // => false
Number.isNaN(Number('-1.1')); // => false
Number.isNaN(Number('asdf')); // => true
Number.isNaN(Number(undefined)); // => true
// Special notation cases that are handled properly
Number.isNaN(Number('1e1')); // => false
Number.isNaN(Number('1e-1')); // => false
Number.isNaN(Number('-1e1')); // => false
Number.isNaN(Number('-1e-1')); // => false
Number.isNaN(Number('0b1')); // => false
Number.isNaN(Number('0o1')); // => false
Number.isNaN(Number('0xa')); // => false
// Edge cases that will FAIL if not guarded against
Number.isNaN(Number('')); // => false
Number.isNaN(Number(' ')); // => false
Number.isNaN(Number(null)); // => false
// Edge cases that are debatable
Number.isNaN(Number('-0b1')); // => true
Number.isNaN(Number('-0o1')); // => true
Number.isNaN(Number('-0xa')); // => true
Number.isNaN(Number('Infinity')); // => false
Number.isNaN(Number('INFINITY')); // => true
Number.isNaN(Number('-Infinity')); // => false
Number.isNaN(Number('-INFINITY')); // => true
当不保护空字符串和null时
使用parseInt:
// Base cases that are handled properly
Number.isNaN(parseInt('1')); // => false
Number.isNaN(parseInt('-1')); // => false
Number.isNaN(parseInt('1.1')); // => false
Number.isNaN(parseInt('-1.1')); // => false
Number.isNaN(parseInt('asdf')); // => true
Number.isNaN(parseInt(undefined)); // => true
Number.isNaN(parseInt('')); // => true
Number.isNaN(parseInt(' ')); // => true
Number.isNaN(parseInt(null)); // => true
// Special notation cases that are handled properly
Number.isNaN(parseInt('1e1')); // => false
Number.isNaN(parseInt('1e-1')); // => false
Number.isNaN(parseInt('-1e1')); // => false
Number.isNaN(parseInt('-1e-1')); // => false
Number.isNaN(parseInt('0b1')); // => false
Number.isNaN(parseInt('0o1')); // => false
Number.isNaN(parseInt('0xa')); // => false
// Edge cases that are debatable
Number.isNaN(parseInt('-0b1')); // => false
Number.isNaN(parseInt('-0o1')); // => false
Number.isNaN(parseInt('-0xa')); // => false
Number.isNaN(parseInt('Infinity')); // => true
Number.isNaN(parseInt('INFINITY')); // => true
Number.isNaN(parseInt('-Infinity')); // => true
Number.isNaN(parseInt('-INFINITY')); // => true
使用parseFloat:
// Base cases that are handled properly
Number.isNaN(parseFloat('1')); // => false
Number.isNaN(parseFloat('-1')); // => false
Number.isNaN(parseFloat('1.1')); // => false
Number.isNaN(parseFloat('-1.1')); // => false
Number.isNaN(parseFloat('asdf')); // => true
Number.isNaN(parseFloat(undefined)); // => true
Number.isNaN(parseFloat('')); // => true
Number.isNaN(parseFloat(' ')); // => true
Number.isNaN(parseFloat(null)); // => true
// Special notation cases that are handled properly
Number.isNaN(parseFloat('1e1')); // => false
Number.isNaN(parseFloat('1e-1')); // => false
Number.isNaN(parseFloat('-1e1')); // => false
Number.isNaN(parseFloat('-1e-1')); // => false
Number.isNaN(parseFloat('0b1')); // => false
Number.isNaN(parseFloat('0o1')); // => false
Number.isNaN(parseFloat('0xa')); // => false
// Edge cases that are debatable
Number.isNaN(parseFloat('-0b1')); // => false
Number.isNaN(parseFloat('-0o1')); // => false
Number.isNaN(parseFloat('-0xa')); // => false
Number.isNaN(parseFloat('Infinity')); // => false
Number.isNaN(parseFloat('INFINITY')); // => true
Number.isNaN(parseFloat('-Infinity')); // => false
Number.isNaN(parseFloat('-INFINITY')); // => true
笔记:
只有字符串、空值和未初始化值被认为与解决原始问题保持一致。如果考虑的值是数组和对象,则存在其他边情况。二进制、八进制、十六进制和指数表示法中的字符不区分大小写(即:“0xFF”、“0xFF”和“0xFF”等在上述测试用例中都会产生相同的结果)。在某些情况下,与Infinity(区分大小写)不同,Number和Math对象中的常量以字符串格式作为测试用例传递给上述任何方法,将被确定为不是数字。请参阅此处,了解如何将参数转换为数字,以及为什么存在空字符串和空字符串的边情况。
如果你喜欢一种巧妙的方式,并且你喜欢让同事感到困惑,你可以使用:
const isNumeric = str => parseFloat(str) === parseFloat(str)
证明:
const isNumeric=str=>parseFloat(str)===parseFloit(str)console.log(isNumeric(“10”))console.log(isNumeric('-10.2'))console.log(isNumeric('15abc'))console.log(isNumeric('0.0001'))console.log(isNumeric('abc'))console.log(isNumeric('abc123'))
这里是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;
};
})();