我希望在与旧的 VB6IsNumeric()
函数相同的概念空间中有一些东西?
44 回答
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
如果您只是想检查一个字符串是否是一个整数(没有小数位),那么正则表达式是一个不错的方法。其他方法,例如isNaN
对于如此简单的事情来说太复杂了。
function isNumeric(value) {
return /^-?\d+$/.test(value);
}
console.log(isNumeric('abcd')); // false
console.log(isNumeric('123a')); // false
console.log(isNumeric('1')); // true
console.log(isNumeric('1234567890')); // true
console.log(isNumeric('-23')); // true
console.log(isNumeric(1234)); // true
console.log(isNumeric(1234n)); // true
console.log(isNumeric('123.4')); // false
console.log(isNumeric('')); // false
console.log(isNumeric(undefined)); // false
console.log(isNumeric(null)); // false
只允许正整数使用这个:
function isNumeric(value) {
return /^\d+$/.test(value);
}
console.log(isNumeric('123')); // true
console.log(isNumeric('-23')); // false
你可以走正则表达式的方式:
var num = "987238";
if(num.match(/^-?\d+$/)){
//valid integer (positive or negative)
}else if(num.match(/^\d+\.\d+$/)){
//valid float
}else{
//not valid number
}
这个问题的公认答案有很多缺陷(正如其他几个用户所强调的那样)。这是在 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
如果你真的想确保一个字符串只包含一个数字、任何数字(整数或浮点数)以及完全是一个数字,你不能使用parseInt()
/ parseFloat()
、Number()
或单独使用!isNaN()
。请注意,这!isNaN()
实际上是在返回true
时Number()
返回一个数字,以及false
何时返回NaN
,所以我将把它排除在讨论的其余部分之外。
问题在于,如果字符串包含任何数字,它将返回一个数字,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()
(and 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))
}
试试isNan 函数:
isNaN() 函数判断一个值是否为非法数字(Not-a-Number)。
如果值等于 NaN,则此函数返回 true。否则返回false。
此函数不同于数字特定的Number.isNaN()方法。
全局 isNaN() 函数,将测试值转换为数字,然后对其进行测试。
Number.isNan() 不会将值转换为数字,并且不会为任何非数字类型的值返回 true...
老问题,但在给定的答案中缺少几点。
科学计数法。
!isNaN('1e+30')
是true
,但是在大多数情况下,当人们询问数字时,他们不想匹配1e+30
.
大的浮点数可能表现得很奇怪
观察(使用 Node.js):
> var s = Array(16 + 1).join('9')
undefined
> s.length
16
> s
'9999999999999999'
> !isNaN(s)
true
> Number(s)
10000000000000000
> String(Number(s)) === s
false
>
另一方面:
> var s = Array(16 + 1).join('1')
undefined
> String(Number(s)) === s
true
> var s = Array(15 + 1).join('9')
undefined
> String(Number(s)) === s
true
>
因此,如果您期望String(Number(s)) === s
,那么最好将您的字符串限制为最多 15 位(在省略前导零之后)。
无穷
> typeof Infinity
'number'
> !isNaN('Infinity')
true
> isFinite('Infinity')
false
>
鉴于这一切,检查给定的字符串是一个满足以下所有条件的数字:
- 非科学记数法
- 可预测的转换
Number
和返回String
- 有限
不是一件容易的事。这是一个简单的版本:
function isNonScientificNumberString(o) {
if (!o || typeof o !== 'string') {
// Should not be given anything but strings.
return false;
}
return o.length <= 15 && o.indexOf('e+') < 0 && o.indexOf('E+') < 0 && !isNaN(o) && isFinite(o);
}
然而,即使是这一点也远未完成。此处不处理前导零,但它们确实会影响长度测试。
我已经测试过,迈克尔的解决方案是最好的。投票给他上面的答案(在此页面中搜索“如果您真的想确保一个字符串”以找到它)。本质上,他的回答是这样的:
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);
或者
return (+num === +num);
对 /\s/、null、""、true、false、[](和其他?)进行特殊处理
2019:包括 ES3、ES6 和 TypeScript 示例
也许这已经被重新讨论了太多次,但是我今天也和这个打了一架,想发布我的答案,因为我没有看到任何其他简单或彻底的答案:
ES3
var isNumeric = function(num){
return (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num);
}
ES6
const isNumeric = (num) => (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num);
打字稿
const isNumeric = (num: any) => (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num as number);
这看起来很简单,涵盖了我在许多其他帖子中看到的所有基础并自己想出了:
// Positive Cases
console.log(0, isNumeric(0) === true);
console.log(1, isNumeric(1) === true);
console.log(1234567890, isNumeric(1234567890) === true);
console.log('1234567890', isNumeric('1234567890') === true);
console.log('0', isNumeric('0') === true);
console.log('1', isNumeric('1') === true);
console.log('1.1', isNumeric('1.1') === true);
console.log('-1', isNumeric('-1') === true);
console.log('-1.2354', isNumeric('-1.2354') === true);
console.log('-1234567890', isNumeric('-1234567890') === true);
console.log(-1, isNumeric(-1) === true);
console.log(-32.1, isNumeric(-32.1) === true);
console.log('0x1', isNumeric('0x1') === true); // Valid number in hex
// Negative Cases
console.log(true, isNumeric(true) === false);
console.log(false, isNumeric(false) === false);
console.log('1..1', isNumeric('1..1') === false);
console.log('1,1', isNumeric('1,1') === false);
console.log('-32.1.12', isNumeric('-32.1.12') === false);
console.log('[blank]', isNumeric('') === false);
console.log('[spaces]', isNumeric(' ') === false);
console.log('null', isNumeric(null) === false);
console.log('undefined', isNumeric(undefined) === false);
console.log([], isNumeric([]) === false);
console.log('NaN', isNumeric(NaN) === false);
您还可以尝试自己的isNumeric
功能,然后在这些用例中过去并扫描所有这些用例的“真”。
或者,查看每个返回的值:
将参数传递给其构造函数时,可以使用Number的结果。
如果参数(字符串)无法转换为数字,则返回 NaN,因此您可以确定提供的字符串是否为有效数字。
注意事项:注意当传递空字符串或 '\t\t'
and '\n\t'
as Number时会返回0;传递 true 将返回 1,而 false 返回 0。
Number('34.00') // 34
Number('-34') // -34
Number('123e5') // 12300000
Number('123e-5') // 0.00123
Number('999999999999') // 999999999999
Number('9999999999999999') // 10000000000000000 (integer accuracy up to 15 digit)
Number('0xFF') // 255
Number('Infinity') // Infinity
Number('34px') // NaN
Number('xyz') // NaN
Number('true') // NaN
Number('false') // NaN
// cavets
Number(' ') // 0
Number('\t\t') // 0
Number('\n\t') // 0
也许有一两个遇到这个问题的人需要比平时更严格的检查(就像我一样)。在这种情况下,这可能很有用:
if(str === String(Number(str))) {
// it's a "perfectly formatted" number
}
谨防!这将拒绝像.1
, 40.000
, 080
,之类的字符串00.1
。它非常挑剔 - 字符串必须与该测试通过的数字的“最小完美形式”匹配。
它使用String
andNumber
构造函数将字符串转换为数字并再次返回,从而检查 JavaScript 引擎的“完美最小形式”(使用初始Number
构造函数转换为的形式)是否与原始字符串匹配。
为什么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));
};
除了手动测试我将在当前困境中遇到的少数用例之外,我还没有通过其他方式对这些中的任何一个进行过很多测试,这些都是非常标准的东西。这是一种“站在巨人的肩膀上”的局面。
它对 TypeScript 无效,因为:
declare function isNaN(number: number): boolean;
对于 TypeScript,您可以使用:
/^\d+$/.test(key)
2019:实用且严格的数值有效性检查
通常,“有效数”是指不包括 NaN 和 Infinity 的 Javascript 数,即“有限数”。
要检查值的数值有效性(例如来自外部源),您可以在 ESlint Airbnb 样式中定义:
/**
* Returns true if 'candidate' is a finite number or a string referring (not just 'including') a finite number
* To keep in mind:
* Number(true) = 1
* Number('') = 0
* Number(" 10 ") = 10
* !isNaN(true) = true
* parseFloat('10 a') = 10
*
* @param {?} candidate
* @return {boolean}
*/
function isReferringFiniteNumber(candidate) {
if (typeof (candidate) === 'number') return Number.isFinite(candidate);
if (typeof (candidate) === 'string') {
return (candidate.trim() !== '') && Number.isFinite(Number(candidate));
}
return false;
}
并以这种方式使用它:
if (isReferringFiniteNumber(theirValue)) {
myCheckedValue = Number(theirValue);
} else {
console.warn('The provided value doesn\'t refer to a finite number');
}
TL;博士
这在很大程度上取决于您要解析为数字的内容。
内置函数比较
由于没有一个现有的资源能满足我的灵魂,我试图弄清楚这些函数到底发生了什么。
这个问题的三个直接答案感觉就像:
!isNaN(input)
(给出与 相同的输出+input === +input
)!isNaN(parseFloat(input))
isFinite(input)
但是它们中的任何一个在每种情况下都是正确的吗?
我在几个案例中测试了这些函数,并生成了降价输出。这是它的样子:
input |
!isNaN(input) 或者+input===+input |
!isNaN( parseFloat( input)) |
isFinite( input) |
评论 |
---|---|---|---|---|
123 | ✔️ | ✔️ | ✔️ | - |
'123' | ✔️ | ✔️ | ✔️ | - |
12.3 | ✔️ | ✔️ | ✔️ | - |
'12.3' | ✔️ | ✔️ | ✔️ | - |
'12.3' | ✔️ | ✔️ | ✔️ | 正如预期的那样,修剪了空白。 |
1_000_000 | ✔️ | ✔️ | ✔️ | 数字分隔符可以理解,也可以预期。 |
'1_000_000' | ❌</td> | ✔️ | ❌</td> | 惊喜!JS 只是不会解析字符串中的数字分隔符。有关详细信息,请检查此问题。(为什么然后解析为浮点数?好吧,它没有。) |
'0b11111111' | ✔️ | ✔️ | ✔️ | 二进制形式理解,因为它应该。 |
'0o377' | ✔️ | ✔️ | ✔️ | 八进制形式也可以理解。 |
'0xFF' | ✔️ | ✔️ | ✔️ | 当然可以理解十六进制。有人有其他想法吗? |
'' | ✔️ | ❌</td> | ✔️ | 空字符串应该是数字吗? |
'' | ✔️ | ❌</td> | ✔️ | 只有空格的字符串应该是数字吗? |
'ABC' | ❌</td> | ❌</td> | ❌</td> | 每个人都同意,而不是一个数字。 |
'12.34Ab!@#$' | ❌</td> | ✔️ | ❌</td> | 啊! 现在很容易理解是做什么的parseFloat() 。对我来说并不令人印象深刻,但在某些情况下可能会派上用场。 |
'10e100' | ✔️ | ✔️ | ✔️ | 10 100确实是一个数字。 但是要小心!它比最大安全整数值 2 53(大约 9×10 15)大得多。阅读本文了解详情。 |
'10e1000' | ✔️ | ✔️ | ❌</td> | 跟我说,救命! 虽然不像看起来那么疯狂。在 JavaScript 中,大于 ~10 308的值会四舍五入为无穷大,这就是原因。在这里查看详细信息。 是的, isNaN() 将无穷大视为一个数字,并将parseFloat() 无穷大解析为无穷大。 |
空值 | ✔️ | ❌</td> | ✔️ | 现在这很尴尬。在 JS 中,当需要转换时,null 变为零,我们得到一个有限数。 那么这里为什么 parseFloat(null) 要返回一个NaN 呢?有人请给我解释一下这个设计概念。 |
不明确的 | ❌</td> | ❌</td> | ❌</td> | 正如预期的那样。 |
无穷 | ✔️ | ✔️ | ❌</td> | 如前所述,isNaN() 将无穷大视为一个数字,并将parseFloat() 无穷大解析为无穷大。 |
那么......他们中的哪一个是“正确的”?
现在应该清楚了,这在很大程度上取决于我们需要什么。例如,我们可能希望将 null 输入视为 0。在这种情况下isFinite()
可以正常工作。
isNaN()
同样,当需要将10 10000000000视为有效数字时,也许我们会得到一点帮助(尽管问题仍然存在——为什么会这样,以及我们将如何处理)!
当然,我们可以手动排除任何场景。
就像在我的情况下一样,我需要 的输出isFinite()
,除了 null 情况、空字符串情况和只有空格的字符串情况。此外,我对非常庞大的数字也不感到头疼。所以我的代码看起来像这样:
/**
* My necessity was met by the following code.
*/
if (input === null) {
// Null input
} else if (input.trim() === '') {
// Empty or whitespace-only string
} else if (isFinite(input)) {
// Input is a number
} else {
// Not a number
}
而且,这是我生成表格的 JavaScript:
/**
* Note: JavaScript does not print numeric separator inside a number.
* In that single case, the markdown output was manually corrected.
* Also, the comments were manually added later, of course.
*/
let inputs = [
123, '123', 12.3, '12.3', ' 12.3 ',
1_000_000, '1_000_000',
'0b11111111', '0o377', '0xFF',
'', ' ',
'abc', '12.34Ab!@#$',
'10e100', '10e1000',
null, undefined, Infinity];
let markdownOutput = `| \`input\` | \`!isNaN(input)\` or <br>\`+input === +input\` | \`!isNaN(parseFloat(input))\` | \`isFinite(input)\` | Comment |
| :---: | :---: | :---: | :---: | :--- |\n`;
for (let input of inputs) {
let outputs = [];
outputs.push(!isNaN(input));
outputs.push(!isNaN(parseFloat(input)));
outputs.push(isFinite(input));
if (typeof input === 'string') {
// Output with quotations
console.log(`'${input}'`);
markdownOutput += `| '${input}'`;
} else {
// Output without quotes
console.log(input);
markdownOutput += `| ${input}`;
}
for (let output of outputs) {
console.log('\t' + output);
if (output === true) {
markdownOutput += ` | <div style="color:limegreen">true</div>`;
// markdownOutput += ` | ✔️`; // for stackoverflow
} else {
markdownOutput += ` | <div style="color:orangered">false</div>`;
// markdownOutput += ` | ❌`; // for stackoverflow
}
}
markdownOutput += ` ||\n`;
}
// Replace two or more whitespaces with $nbsp;
markdownOutput = markdownOutput.replaceAll(` `, ` `);
// Print markdown to console
console.log(markdownOutput);
有人也可能从基于正则表达式的答案中受益。这里是:
一个衬垫是整数:
const isInteger = num => /^-?[0-9]+$/.test(num+'');
一班是数字:接受整数和小数
const isNumeric = num => /^-?[0-9]+(?:\.[0-9]+)?$/.test(num+'');
parseInt(),但请注意,这个函数有点不同,例如它为 parseInt("100px") 返回 100。
引用:
isNaN(num) // 如果变量不包含有效数字,则返回 true
如果您需要检查前导/尾随空格,则不完全正确 - 例如,当需要一定数量的数字时,您可能需要获取 '1111' 而不是 '111' 或 '111' 作为 PIN输入。
更好地使用:
var num = /^\d+$/.test(num)
当防止空字符串和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
- 有关如何将参数转换为 a以及为什么存在空字符串和空字符串的边缘情况的说明,请参见此处。
Number
null
好吧,我正在使用我制作的这个......
到目前为止它一直在工作:
function checkNumber(value) {
return value % 1 == 0;
}
如果您发现它有任何问题,请告诉我。
如果有人能做到这一点,我会花一些时间来尝试修补 moment.js ( https://github.com/moment/moment )。这是我从中拿走的东西:
function isNumeric(val) {
var _val = +val;
return (val !== val + 1) //infinity check
&& (_val === +val) //Cute coercion check
&& (typeof val !== 'object') //Array/object check
}
处理以下情况:
真的!:
isNumeric("1"))
isNumeric(1e10))
isNumeric(1E10))
isNumeric(+"6e4"))
isNumeric("1.2222"))
isNumeric("-1.2222"))
isNumeric("-1.222200000000000000"))
isNumeric("1.222200000000000000"))
isNumeric(1))
isNumeric(0))
isNumeric(-0))
isNumeric(1010010293029))
isNumeric(1.100393830000))
isNumeric(Math.LN2))
isNumeric(Math.PI))
isNumeric(5e10))
错误的!:
isNumeric(NaN))
isNumeric(Infinity))
isNumeric(-Infinity))
isNumeric())
isNumeric(undefined))
isNumeric('[1,2,3]'))
isNumeric({a:1,b:2}))
isNumeric(null))
isNumeric([1]))
isNumeric(new Date()))
具有讽刺意味的是,我最挣扎的是:
isNumeric(new Number(1)) => false
欢迎任何建议。:]
我最近写了一篇关于如何确保变量是有效数字的文章:https ://github.com/jehugaleahsa/artifacts/blob/master/2018/typescript_num_hack.md文章解释了如何确保浮点或整数,如果是的话重要(+x
vs ~~x
)。
本文假设变量是 astring
或 anumber
开头并且trim
可用/填充。扩展它以处理其他类型也不难。这是它的肉:
// 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
}
function isNumberCandidate(s) {
const str = (''+ s).trim();
if (str.length === 0) return false;
return !isNaN(+str);
}
console.log(isNumberCandidate('1')); // true
console.log(isNumberCandidate('a')); // false
console.log(isNumberCandidate('000')); // true
console.log(isNumberCandidate('1a')); // false
console.log(isNumberCandidate('1e')); // false
console.log(isNumberCandidate('1e-1')); // true
console.log(isNumberCandidate('123.3')); // true
console.log(isNumberCandidate('')); // false
console.log(isNumberCandidate(' ')); // false
console.log(isNumberCandidate(1)); // true
console.log(isNumberCandidate(0)); // true
console.log(isNumberCandidate(NaN)); // false
console.log(isNumberCandidate(undefined)); // false
console.log(isNumberCandidate(null)); // false
console.log(isNumberCandidate(-1)); // true
console.log(isNumberCandidate('-1')); // true
console.log(isNumberCandidate('-1.2')); // true
console.log(isNumberCandidate(0.0000001)); // true
console.log(isNumberCandidate('0.0000001')); // true
console.log(isNumberCandidate(Infinity)); // true
console.log(isNumberCandidate(-Infinity)); // true
console.log(isNumberCandidate('Infinity')); // true
if (isNumberCandidate(s)) {
// use +s as a number
+s ...
}
这是建立在以前的一些答案和评论的基础上的。以下内容涵盖了所有边缘情况,也相当简洁:
const isNumRegEx = /^-?(\d*\.)?\d+$/;
function isNumeric(n, allowScientificNotation = false) {
return allowScientificNotation ?
!Number.isNaN(parseFloat(n)) && Number.isFinite(n) :
isNumRegEx.test(n);
}
检查JS中的数字:
检查它是否是数字的最佳方法:
isFinite(20) //True
从字符串中读取一个值。CSS *:
parseInt('2.5rem') //2 parseFloat('2.5rem') //2.5
对于整数:
isInteger(23 / 0) //False
如果值为 NaN:
isNaN(20) //False
PFB 工作解决方案:
function(check){
check = check + "";
var isNumber = check.trim().length>0? !isNaN(check):false;
return isNumber;
}
免去寻找“内置”解决方案的麻烦。
没有一个好的答案,而且这个帖子中被高度评价的答案是错误的。
npm install is-number
在 JavaScript 中,可靠地检查一个值是否为数字并不总是那么简单。开发人员通常使用 +、- 或 Number() 将字符串值转换为数字(例如,当从用户输入、正则表达式匹配、解析器等返回值时)。但是有许多非直观的边缘情况会产生意想不到的结果:
console.log(+[]); //=> 0
console.log(+''); //=> 0
console.log(+' '); //=> 0
console.log(typeof NaN); //=> 'number'
这似乎抓住了看似无限数量的边缘情况:
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;
};
因此,这将取决于您希望它处理的测试用例。
function isNumeric(number) {
return !isNaN(parseFloat(number)) && !isNaN(+number);
}
我正在寻找的是 javascript 中的常规数字类型。
0, 1 , -1, 1.1 , -1.1 , 1E1 , -1E1 , 1e1 , -1e1, 0.1e10, -0.1.e10 , 0xAF1 , 0o172, Math.PI, Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY
它们也是字符串的表示形式:
'0', '1', '-1', '1.1', '-1.1', '1E1', '-1E1', '1e1', '-1e1', '0.1e10', '-0.1.e10', '0xAF1', '0o172'
我确实想省略而不是将它们标记为数字
'', ' ', [], {}, null, undefined, NaN
截至今天,所有其他答案似乎都未能通过其中一个测试用例。
我用这个函数作为表单验证工具,不想让用户写指数函数,所以想出了这个函数:
<script>
function isNumber(value, acceptScientificNotation) {
if(true !== acceptScientificNotation){
return /^-{0,1}\d+(\.\d+)?$/.test(value);
}
if (true === Array.isArray(value)) {
return false;
}
return !isNaN(parseInt(value, 10));
}
console.log(isNumber("")); // false
console.log(isNumber(false)); // false
console.log(isNumber(true)); // false
console.log(isNumber("0")); // true
console.log(isNumber("0.1")); // true
console.log(isNumber("12")); // true
console.log(isNumber("-12")); // true
console.log(isNumber(-45)); // true
console.log(isNumber({jo: "pi"})); // false
console.log(isNumber([])); // false
console.log(isNumber([78, 79])); // false
console.log(isNumber(NaN)); // false
console.log(isNumber(Infinity)); // false
console.log(isNumber(undefined)); // false
console.log(isNumber("0,1")); // false
console.log(isNumber("1e-1")); // false
console.log(isNumber("1e-1", true)); // true
</script>
这种方式对我有用。
function isNumeric(num){
let value1 = num.toString();
let value2 = parseFloat(num).toString();
return (value1 === value2);
}
console.log(
isNumeric(123), //true
isNumeric(-123), //true
isNumeric('123'), //true
isNumeric('-123'), //true
isNumeric(12.2), //true
isNumeric(-12.2), //true
isNumeric('12.2'), //true
isNumeric('-12.2'), //true
isNumeric('a123'), //false
isNumeric('123a'), //false
isNumeric(' 123'), //false
isNumeric('123 '), //false
isNumeric('a12.2'), //false
isNumeric('12.2a'), //false
isNumeric(' 12.2'), //false
isNumeric('12.2 '), //false
)
在我的应用程序中,我们只允许 az AZ 和 0-9 个字符。我发现上面使用“ string % 1 === 0”的答案有效,除非字符串以 0xnn(如 0x10)开头,然后当我们不希望它以数字形式返回时。我的数字检查中的以下简单陷阱似乎在我们的特定情况下可以解决问题。
function isStringNumeric(str_input){
//concat a temporary 1 during the modulus to keep a beginning hex switch combination from messing us up
//very simple and as long as special characters (non a-z A-Z 0-9) are trapped it is fine
return '1'.concat(str_input) % 1 === 0;}
警告:这可能是在利用 Javascript 和 Actionscript [Number("1" + the_string) % 1 === 0)] 中的一个长期存在的错误,我不能这么说,但这正是我们所需要的。
我的解决方案:
// returns true for positive ints;
// no scientific notation, hexadecimals or floating point dots
var isPositiveInt = function(str) {
var result = true, chr;
for (var i = 0, n = str.length; i < n; i++) {
chr = str.charAt(i);
if ((chr < "0" || chr > "9") && chr != ",") { //not digit or thousands separator
result = false;
break;
};
if (i == 0 && (chr == "0" || chr == ",")) { //should not start with 0 or ,
result = false;
break;
};
};
return result;
};
您可以在循环内添加其他条件,以满足您的特定需求。
我的尝试有点令人困惑,也许不是最好的解决方案
function isInt(a){
return a === ""+~~a
}
console.log(isInt('abcd')); // false
console.log(isInt('123a')); // false
console.log(isInt('1')); // true
console.log(isInt('0')); // true
console.log(isInt('-0')); // false
console.log(isInt('01')); // false
console.log(isInt('10')); // true
console.log(isInt('-1234567890')); // true
console.log(isInt(1234)); // false
console.log(isInt('123.4')); // false
console.log(isInt('')); // false
// other types then string returns false
console.log(isInt(5)); // false
console.log(isInt(undefined)); // false
console.log(isInt(null)); // false
console.log(isInt('0x1')); // false
console.log(isInt(Infinity)); // false
您可以使用类型(例如流库)来获得静态的编译时检查。当然对于用户输入不是非常有用。
// @flow
function acceptsNumber(value: number) {
// ...
}
acceptsNumber(42); // Works!
acceptsNumber(3.14); // Works!
acceptsNumber(NaN); // Works!
acceptsNumber(Infinity); // Works!
acceptsNumber("foo"); // Error!
这是 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;
};
})();
测试字符串或数字是否为数字
const isNumeric = stringOrNumber =>
stringOrNumber == 0 || !!+stringOrNumber;
或者,如果您想将字符串或数字转换为数字
const toNumber = stringOrNumber =>
stringOrNumber == 0 || +stringOrNumber ? +stringOrNumber : NaN;
如果您正在寻找一个正数(例如门牌号),只需使用:
if (mystring > 0) ...
我在 Angular 中使用了这个功能
isNumeric(value: string): boolean {
let valueToNumber = Number(value);
var result = typeof valueToNumber == 'number' ;
if(valueToNumber.toString() == 'NaN')
{
result = false;
}
return result;
}
sNum
这是一个检查是否是有效数值的单行代码;它已经针对各种输入进行了测试:
!!s && !isNaN(+s.replace(/\s|\$/g, '')); // returns True if numeric value
向@gman 致敬以发现错误。
我喜欢这种简单。
Number.isNaN(Number(value))
以上是常规的 Javascript,但我将它与typescript typeguard结合使用以进行智能类型检查。这对于打字稿编译器为您提供正确的智能感知非常有用,并且没有类型错误。
打字稿类型保护
isNotNumber(value: string | number): value is string {
return Number.isNaN(Number(this.smartImageWidth));
}
isNumber(value: string | number): value is number {
return Number.isNaN(Number(this.smartImageWidth)) === false;
}
假设您有一个属性width
是number | string
. 您可能希望根据它是否为字符串来执行逻辑。
var width: number|string;
width = "100vw";
if (isNotNumber(width))
{
// the compiler knows that width here must be a string
if (width.endsWith('vw'))
{
// we have a 'width' such as 100vw
}
}
else
{
// the compiler is smart and knows width here must be number
var doubleWidth = width * 2;
}
typeguard 足够聪明,可以width
将if
语句中的类型限制为 ONLY string
。这允许编译器width.endsWith(...)
允许如果类型是string | number
.
您可以随意调用 typeguard isNotNumber
, isNumber
, isString
,isNotString
但我认为isString
这有点模棱两可且难以阅读。
只需使用isNaN()
,这会将字符串转换为数字,如果得到有效数字,将返回false
...
isNaN("Alireza"); //return true
isNaN("123"); //return false
我正在使用以下内容:
const isNumber = s => !isNaN(+s)
我这样做:
function isString(value)
{
return value.length !== undefined;
}
function isNumber(value)
{
return value.NaN !== undefined;
}
当然,如果您传递一些其他定义了“长度”的对象,isString() 将在这里被绊倒。