JavaScript中的(内置)方式,用于检查字符串是否为有效数字

Ele*_*hoy 1051 javascript validation numeric

我希望在旧的VB6 IsNumeric()功能的同一个概念空间中有什么东西?

Dan*_*Dan 2110

要检查变量(包括字符串)是否为数字,请检查它是否不是数字:

无论变量包含的是字符串还是数字,这都有效.

isNaN(num)         // returns true if the variable does NOT contain a valid number
Run Code Online (Sandbox Code Playgroud)

例子

isNaN(123)         // false
isNaN('123')       // false
isNaN('1e10000')   // false (This translates to Infinity, which is a number)
isNaN('foo')       // true
isNaN('10px')      // true
Run Code Online (Sandbox Code Playgroud)

当然,如果需要,你可以否定这一点.例如,要实现IsNumeric您给出的示例:

function isNumeric(num){
  return !isNaN(num)
}
Run Code Online (Sandbox Code Playgroud)

要将包含数字的字符串转换为数字:

仅当字符串包含数字字符时才有效,否则返回NaN.

+num               // returns the numeric value of the string, or NaN 
                   // if the string isn't purely numeric characters
Run Code Online (Sandbox Code Playgroud)

例子

+'12'              // 12
+'12.'             // 12
+'12..'            // Nan
+'.12'             // 0.12
+'..12'            // Nan
+'foo'             // NaN
+'12px'            // NaN
Run Code Online (Sandbox Code Playgroud)

将字符串松散地转换为数字

用于将'12px'转换为12,例如:

parseInt(num)      // extracts a numeric value from the 
                   // start of the string, or NaN.
Run Code Online (Sandbox Code Playgroud)

例子

parseInt('12')     // 12
parseInt('aaa')    // NaN
parseInt('12px')   // 12
parseInt('foo2')   // NaN      These last two may be different
parseInt('12a5')   // 12       from what you expected to see. 
Run Code Online (Sandbox Code Playgroud)

花车

记住,不像熊+num,parseInt(顾名思义)将一个float转换为整数通过斩去一切小数点后面(如果你想使用parseInt() ,因为这种行为,你可能会更好过使用其他方法代替) :

+'12.345'          // 12.345
parseInt(12.345)   // 12
parseInt('12.345') // 12
Run Code Online (Sandbox Code Playgroud)

空字符串

空字符串可能有点违反直觉.+num将空字符串转换为零,并isNaN()假设相同:

+''                // 0
isNaN('')          // false
Run Code Online (Sandbox Code Playgroud)

parseInt()不同意:

parseInt('')       // NaN
Run Code Online (Sandbox Code Playgroud)

  • 关于parseInt的一个非常重要的注意事项是它允许你指定一个基数来将字符串转换为int.这是一个很大的问题,因为如果你不提供它,它会试图为你猜测一个基数.因此,例如:parseInt("17")导致17(十进制,10),但是parseInt("08")导致0(八进制,8).因此,除非您不打算,否则最安全的方法是使用parseInt(number,10),明确指定10作为基数. (123认同)
  • 这是完全错误的 - 它如何获得如此多的赞成?你不能使用`isNaN`"检查一个变量是不是一个数字"."不是数字"与"IEEE-794 NaN"不同,这是`isNaN`测试的.特别是,至少在测试布尔值和空字符串时,这种用法会失败.请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN#Description. (97认同)
  • 检查某些东西是否为数字的最快方法是"等于自我"检查:`var n ='a'; if(+ n === + n){//是数字}`比最新版本的Chrome中的isNaN快〜3994%.请参阅此处的性能测试:http://jsperf.com/isnan-vs-typeof/5 (40认同)
  • 注意!isNaN(undefined)返回false. (29认同)
  • **警告**这个答案是错误的.使用风险由您自己承担.示例:`isNaN(1 + false + parseInt("1.您信任您的用户吗?"))` (17认同)
  • `isNaN('')== false`所以空格是有效数字?! (6认同)
  • 注意isNaN(true)和isNaN(false)将始终返回false!所以布尔值也是这个函数的数字) (5认同)
  • `!isNaN(false)= true`所以false是一个数字? (4认同)
  • 这是错误的。版主,请考虑将此答案标记为可能包含低质量信息。一方面,IsNaN("") 返回 false,这显然是不正确的。这就像对空盘子说 isSandwich 一样。 (4认同)
  • Downvote因为isNaN也使用charcode 9返回false,可能与其他"奇怪"的charcodes一起发生. (3认同)
  • @ Arman-Bimatov,那是因为NaN!== NaN.要检查parseInt(x)的结果是否不是数字,你要检查isNaN(parseInt(x)) (3认同)
  • 如果使用isNaN - 请注意以下危险参数,其中isNaN将返回false:```isNaN([]),isNaN([234]),isNaN(null),isNaN(true),isNaN(false), isNaN(''),isNaN('')```.最后一个是一个或多个空格的字符串. (3认同)
  • 如果猜测非数字字符为基数,则""字符串"不能可靠地返回NaN.尝试+"0x30" (2认同)
  • 实际上,当检查:`parseInt('') === NaN`时 - 它失败了。尽管如此,在控制台窗口中打印它:`parseInt(''); // 打印 NaN`。诡异的 (2认同)
  • @dcsan false 和 true 可以解释为 0 和 1。`false + true + true + false + true;` 等于 3(如 0 + 1 + 1 + 0 + 1)。所以是的。请参阅 @corvec 的评论,您应该使用 `!isNaN(parseInt(false))` 代替,它将返回 false (2认同)
  • @Dan 也许应该在这个答案中添加 `isFinite` 函数。https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite (2认同)
  • 检查[这个答案](/sf/answers/3709045301/)。它比公认的解决方案效果更好。 (2认同)
  • @Kevin Jurkowski,n => {return +n === +n} 对于以下项返回 true:[]、[2]、[undefined]、''、(new Date())、true 和 false。 (2认同)
  • NaN 代表“Not a Number”,因此如果“Number.isNaN(x)”为 true,则意味着“x”显然不是一个数字。 (2认同)

roe*_*ing 48

你可以去RegExp方式:

var num = "987238";

if(num.match(/^-{0,1}\d+$/)){
  //valid integer (positive or negative)
}else if(num.match(/^\d+\.\d+$/)){
  //valid float
}else{
  //not valid number
}
Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下,RegExp ==坏 (35认同)
  • @JoelCoehoorn关心为什么RegExp ==这里不好?对我来说似乎是一个有效的用例. (14认同)
  • 这在十六进制数字(例如0x12)上失败,浮点数没有前导零(例如.42)和负数. (9认同)
  • 有许多方法比构建一个数字(另一个注释中的十六进制数字只是一个例子),并且有许多数字可能被认为无效(溢出类型,太精确等).此外,正则表达式比使用内置机制更慢,更复杂 (5认同)
  • 还应该匹配科学计数法... 1e10 等。 (2认同)

Gav*_*vin 40

如果你只是想检查字符串是否是一个整数(没有小数位),正则表达式是一个很好的方法.其他方法如isNaN对于如此简单的事情来说太复杂了.

function isNumeric(value) {
    return /^-{0,1}\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('123.4'));        // false
console.log(isNumeric(''));             // false
console.log(isNumeric(undefined));      // false
console.log(isNumeric(null));           // false
Run Code Online (Sandbox Code Playgroud)

要仅允许整数使用此:

function isNumeric(value) {
    return /^\d+$/.test(value);
}

console.log(isNumeric('123'));          // true
console.log(isNumeric('-23'));          // false
Run Code Online (Sandbox Code Playgroud)

  • 的console.log(ISNUMERIC( ' - 1')); (11认同)
  • 也许只是将"isNumeric"重命名为"hasOnlyDigits".在许多情况下,这正是您正在寻找的支票. (7认同)
  • 的console.log(ISNUMERIC( '2E2')); (5认同)
  • 稍微好一点..禁止使用阿拉伯语“/^[0-9]+$/.test(value)”等语言中的数字字符 (5认同)
  • 这就是我正在寻找的,相当于 php ctype_digit (2认同)

Mic*_*ael 35

如果你真的想确保字符串只包含一个数字,任何数字(整数或浮点数),并准确一些,你不能使用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
Run Code Online (Sandbox Code Playgroud)

问题Number()是,如果传递的值根本不是数字,它将返回一个数字!

Number("") // returns 0
Number(" ") // returns 0
Number(" \u00A0   \t\n\r") // returns 0
Run Code Online (Sandbox Code Playgroud)

滚动自己的正则表达式的问题在于,除非您创建用于匹配浮点数的精确正则表达式,因为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))
}
Run Code Online (Sandbox Code Playgroud)

  • 如果数字字符串来自用户输入,情况就是如此。但我认为无论如何我都应该提到空格,因为我认为大多数需要 `isNumber` 函数的人都不会处理用户界面。此外,良好的数字输入不允许以空格开头。 (6认同)
  • 当字符串具有前导或尾随空格时,返回true.''1',''2'和`'3'都返回true. (2认同)
  • @RuudLenders - 大多数人都不会在意是否有尾随空格被删除以使字符串成为有效数字,因为它很容易意外地在许多接口中放入额外的空格. (2认同)

Has*_*bel 35

长话短说

\n

这很大程度上取决于想要解析为数字的内容。

\n

内置函数比较

\n

由于现有的资源都不能满足我的需求,我试图弄清楚这些函数到底发生了什么。

\n

这个问题的三个直接答案是:

\n
    \n
  1. !isNaN(input)(其输出与 相同+input === +input
  2. \n
  3. !isNaN(parseFloat(input))
  4. \n
  5. isFinite(input)
  6. \n
\n

但它们中的任何一个在每种情况下都是正确的吗?

\n

我在几种情况下测试了这些函数,并以降价形式生成输出。它看起来是这样的:

\n
\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
input!isNaN(input)或者
+input===+input
!isNaN(
parseFloat(
input))
isFinite(
input)
评论
123\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f-
\'123\'\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f-
12.3\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f-
'12.3'\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f-
\'\xc2\xa0\xc2\xa0 12.3\xc2\xa0\xc2\xa0 \'\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f正如预期的那样,空白空格已被修剪。
1_000_000\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f数字分隔符已被理解,也是预期的。
\'1_000_000\'\xe2\x9d\x8c\xe2\x9c\x94\xef\xb8\x8f\xe2\x9d\x8c惊喜!JS 只是不会解析字符串内的数字分隔符。有关详细信息,请检查问题。(为什么解析为 float 有效?嗯,它没有。)
\'0b11111111\'\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f二进制形式应该被理解。
\'0o377\'\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f八进制形式也可以理解。
\'0xFF\'\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f当然可以理解十六进制。有人不这么认为吗?
''\xe2\x9c\x94\xef\xb8\x8f\xe2\x9d\x8c\xe2\x9c\x94\xef\xb8\x8f空字符串应该是数字吗?
\'\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\'\xe2\x9c\x94\xef\xb8\x8f\xe2\x9d\x8c\xe2\x9c\x94\xef\xb8\x8f纯空白字符串应该是数字吗?
\'abc\'\xe2\x9d\x8c\xe2\x9d\x8c\xe2\x9d\x8c每个人都同意,而不是一个数字。
\'12.34Ab!@#$\'\xe2\x9d\x8c\xe2\x9c\x94\xef\xb8\x8f\xe2\x9d\x8c啊! 现在已经可以理解它的parseFloat()作用了。对我来说并不令人印象深刻,但在某些情况下可能会派上用场。
\'10e100\'\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f10100确实一个数字。
但要小心!它比最大安全整数值 2 53(大约 9\xc3\x9710 15 )大得多。阅读本文了解详细信息。
\'10e1000\'\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f\xe2\x9d\x8c跟我说一声,救命啊!
尽管并不像看起来那么疯狂。在 JavaScript 中,大于 ~10 308的值会四舍五入为无穷大,这就是原因。查看此处了解详细信息。
是的,isNaN()将无穷大视为一个数字,并将parseFloat()无穷大解析为无穷大。
无效的\xe2\x9c\x94\xef\xb8\x8f\xe2\x9d\x8c\xe2\x9c\x94\xef\xb8\x8f现在这很尴尬。在 JS 中,当需要转换时,null 变成零,我们得到一个有限的数字。
那为什么parseFloat(null)要在这里返回一个NaN呢?请有人向我解释一下这个设计理念。
不明确的\xe2\x9d\x8c\xe2\x9d\x8c\xe2\x9d\x8c正如预期的那样。
无穷\xe2\x9c\x94\xef\xb8\x8f\xe2\x9c\x94\xef\xb8\x8f\xe2\x9d\x8c如前所述,isNaN()将无穷大视为数字,并将parseFloat()无穷大解析为无穷大。
\n
\n

那么......其中哪一个是“正确的”?

\n

现在应该很清楚了,这很大程度上取决于我们需要什么。例如,我们可能希望将空输入视为 0。在这种情况下isFinite()就可以正常工作。

\n

isNaN()再说一次,也许我们会在需要将10 10000000000视为有效数字时得到一点帮助(尽管问题仍然是\xe2\x80\x94为什么会这样,以及我们将如何处理)!

\n

当然,我们可以手动排除任何场景。

\n

就像我的例子一样,我完全需要 的输出isFinite(),除了 null 情况、空字符串情况和仅空白字符串情况。而且我对巨大的数字并不感到头疼。所以我的代码看起来像这样:

\n
/**\n * My necessity was met by the following code.\n */\n\nif (input === null) {\n    // Null input\n} else if (input.trim() === \'\') {\n    // Empty or whitespace-only string\n} else if (isFinite(input)) {\n    // Input is a number\n} else {\n    // Not a number\n}\n
Run Code Online (Sandbox Code Playgroud)\n

而且,这是我生成表格的 JavaScript:

\n
/**\n * Note: JavaScript does not print numeric separator inside a number.\n * In that single case, the markdown output was manually corrected.\n * Also, the comments were manually added later, of course.\n */\n\nlet inputs = [\n    123, \'123\', 12.3, \'12.3\', \'   12.3   \',\n    1_000_000, \'1_000_000\',\n    \'0b11111111\', \'0o377\', \'0xFF\',\n    \'\', \'    \',\n    \'abc\', \'12.34Ab!@#$\',\n    \'10e100\', \'10e1000\',\n    null, undefined, Infinity];\n\nlet markdownOutput = `| \\`input\\` | \\`!isNaN(input)\\` or <br>\\`+input === +input\\` | \\`!isNaN(parseFloat(input))\\` | \\`isFinite(input)\\` | Comment |\n| :---: | :---: | :---: | :---: | :--- |\\n`;\n\nfor (let input of inputs) {\n    let outputs = [];\n    outputs.push(!isNaN(input));\n    outputs.push(!isNaN(parseFloat(input)));\n    outputs.push(isFinite(input));\n\n    if (typeof input === \'string\') {\n        // Output with quotations\n        console.log(`\'${input}\'`);\n        markdownOutput += `| \'${input}\'`;\n    } else {\n        // Output without quotes\n        console.log(input);\n        markdownOutput += `| ${input}`;\n    }\n\n    for (let output of outputs) {\n        console.log(\'\\t\' + output);\n        if (output === true) {\n            markdownOutput += ` | <div style="color:limegreen">true</div>`;\n            // markdownOutput += ` | \xe2\x9c\x94\xef\xb8\x8f`; // for stackoverflow\n        } else {\n            markdownOutput += ` | <div style="color:orangered">false</div>`;\n            // markdownOutput += ` | \xe2\x9d\x8c`; // for stackoverflow\n        }\n    }\n\n    markdownOutput += ` ||\\n`;\n}\n\n// Replace two or more whitespaces with $nbsp;\nmarkdownOutput = markdownOutput.replaceAll(`  `, `&nbsp;&nbsp;`);\n\n// Print markdown to console\nconsole.log(markdownOutput);\n
Run Code Online (Sandbox Code Playgroud)\n


小智 28

JavaScript 全局isFinite()检查值是否是有效(有限)数字。

请参阅 MDN 了解Number.isFinite() 和全局 isFinite() 之间的区别

let a = isFinite('abc') // false
let b = isFinite('123') // true
let c = isFinite('12a') // false
let d = isFinite(null)  // true
console.log(a, b, c, d)
Run Code Online (Sandbox Code Playgroud)

  • isFinite(null) 返回 true! (8认同)

the*_*ear 21

尝试isNan函数:

isNaN()函数确定值是否为非法数字(非数字).

如果值等于NaN,则此函数返回true.否则返回false.

此函数与Number specific Number.isNaN()方法不同.

  全局isNaN()函数,将测试值转换为Number,然后对其进行测试.

Number.isNan()不会将值转换为Number,并且对于任何不是Number类型的值都不会返回true.

  • isFinite是一个更好的检查 - 它处理无限的奇怪的角落情况 (3认同)
  • @MichaelHaren不够好!`isNaN()`为*ANY*字符串返回`false`,仅包含空格字符,包括'\ u00A0'之类的字符. (3认同)
  • 确保添加空字符串的检查.isNaN('')返回false,但在这种情况下你可能希望它返回true. (2认同)
  • 警告:不适用于以下值:null、""(空字符串)和 false。 (2认同)

chi*_*ens 18

有人也可能从基于正则表达式的答案中受益。这里是:

其中一个衬垫是整数:

const isInteger = num => /^-?[0-9]+$/.test(num+'');
Run Code Online (Sandbox Code Playgroud)

一行 isNumeric:接受整数和小数

const isNumeric = num => /^-?[0-9]+(?:\.[0-9]+)?$/.test(num+'');
Run Code Online (Sandbox Code Playgroud)

  • @yoelhalb 空格对于数字来说是无效字符。您可以在传入之前修剪字符串。 (2认同)

Ham*_*eem 17

这个问题的公认答案有很多缺陷(正如其他几个用户所强调的那样).这是在javascript中处理它的最简单且经过验证的方法之一:

function isNumeric(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}
Run Code Online (Sandbox Code Playgroud)

以下是一些很好的测试用例:

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
Run Code Online (Sandbox Code Playgroud)

  • `parseFloat` 对于这个应用程序来说是不够的,因为当它遇到第一个无法解析为数字的字符时,它将返回迄今为止解析的有效数字。例如。`parseFloat('1.1ea10') === 1.1`。 (2认同)
  • 请注意,如果您使用 Number.isNan 和 Number.isFinite,这将不起作用。 (2认同)

mar*_*ark 11

老问题,但在给定的答案中有几点缺失.

科学计数法.

!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
>
Run Code Online (Sandbox Code Playgroud)

另一方面:

> 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
>
Run Code Online (Sandbox Code Playgroud)

因此,如果有人期望String(Number(s)) === s,那么最好将字符串最多限制为15位(省略前导零后).

无穷

> typeof Infinity
'number'
> !isNaN('Infinity')
true
> isFinite('Infinity')
false
>
Run Code Online (Sandbox Code Playgroud)

鉴于此,检查给定字符串是否满足以下所有条件:

  • 非科学记数法
  • 可预测的转换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);
  }
Run Code Online (Sandbox Code Playgroud)

然而,即便是这个还远未完成.这里没有处理前导零,但它们确实拧长度测试.

  • “但是在大多数情况下,当人们要求数字时,他们不想匹配 1e+30 之类的东西” 为什么会这样说?如果有人想知道一个字符串是否包含一个数字,在我看来他们会想知道它是否包含一个数字,而 1e+30 是一个数字。当然,如果我在 JavaScript 中测试一个数字值的字符串,我希望它匹配。 (2认同)

Jer*_*emy 10

2019 年:包括 ES3、ES6 和 TypeScript 示例

也许这已经被重述了太多次,但是我今天也与这个进行了斗争并想发布我的答案,因为我没有看到任何其他答案可以简单或彻底地做到这一点:

ES3

var isNumeric = function(num){
    return (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num);  
}
Run Code Online (Sandbox Code Playgroud)

ES6

const isNumeric = (num) => (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num);
Run Code Online (Sandbox Code Playgroud)

打字稿

const isNumeric = (num: any) => (typeof(num) === 'number' || typeof(num) === "string" && num.trim() !== '') && !isNaN(num as number);
Run Code Online (Sandbox Code Playgroud)

这看起来很简单,涵盖了我在许多其他帖子中看到并自己想到的所有基础:

// 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);
Run Code Online (Sandbox Code Playgroud)

您也可以尝试自己的isNumeric函数,然后在这些用例中过去,然后为所有用例扫描“true”。

或者,查看每个返回的值:

针对 <code>isNumeric()</code> 的每次测试的结果

  • 打字稿版本的类型应该是未知的: const isNumeric = (num:unknown) (3认同)
  • 也适用于科学记数法:`isNumeric('3e2')` / `isNumeric(3e2)` (2认同)

Joh*_*nP2 8

我已经测试过,迈克尔的解决方案是最好的.投票给他上面的答案(搜索此页面"如果你真的想确保一个字符串"找到它).从本质上讲,他的回答如下:

function isNumeric(num){
  num = "" + num; //coerce num to be a string
  return !isNaN(num) && !isNaN(parseFloat(num));
}
Run Code Online (Sandbox Code Playgroud)

它适用于我在此处记录的每个测试用例:https: //jsfiddle.net/wggehvp9/5/

许多其他解决方案因这些边缘情况而失败:'',null,"",true和[].从理论上讲,您可以使用它们,并进行适当的错误处理,例如:

return !isNaN(num);
Run Code Online (Sandbox Code Playgroud)

要么

return (+num === +num);
Run Code Online (Sandbox Code Playgroud)

特殊处理/\s /,null,"",true,false,[](以及其他?)

  • 所以'123'应该是假的,而不是数字,而'1234'应该是一个数字?我喜欢它是什么样的,所以"123"是一个数字,但如果前导空格或尾随空格应该改变值,这可能取决于开发人员的判断. (2认同)

Sim*_*ver 8

我喜欢这种简单性。

Number.isNaN(Number(value))
Run Code Online (Sandbox Code Playgroud)

上面是常规的 Javascript,但我将其与打字稿类型保护程序结合使用以进行智能类型检查。这对于打字稿编译器非常有用,可以为您提供正确的智能感知,并且没有类型错误。

Typescript 打字员

警告:请参阅下面杰里米的评论。这对某些值有一些问题,我现在没有时间修复它,但是使用 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;
}
Run Code Online (Sandbox Code Playgroud)

假设您有一个属性widthnumber | 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;    
}
Run Code Online (Sandbox Code Playgroud)

width类型保护器足够聪明,可以将语句中的类型限制if为 ONLY string。这允许编译器允许width.endsWith(...)如果类型为 则不允许的情况string | number

你可以随意称呼 typeguard isNotNumber, isNumber, isStringisNotString但我认为isString这有点含糊并且难以阅读。

  • 在普通 JS 中工作得相对较好,但会失败,如“1..1”、“1,1”、“-32.1.12”,更重要的是失败“undefined”和“NaN”。不确定你的 TS 是否弥补了这一点,但看起来如果你传递了“undefined”或“NaN”,它会在尝试执行“undefined * 2”时失败,这不会崩溃,但会返回“NaN”。 (2认同)

Gib*_*boK 7

将参数传递给构造函数时,可以使用Number的结果。

如果参数(字符串)不能转换为数字,则返回NaN,因此您可以确定所提供的字符串是否为有效数字。

注意:当传递空字符串或 '\t\t'and '\n\t'作为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
Run Code Online (Sandbox Code Playgroud)


Ult*_*man 7

为什么 jQuery 的实现不够好?

function isNumeric(a) {
    var b = a && a.toString();
    return !$.isArray(a) && b - parseFloat(b) + 1 >= 0;
};
Run Code Online (Sandbox Code Playgroud)

迈克尔提出了这样的建议(虽然我在这里偷了“user1691651 - John”的修改版本):

function isNumeric(num){
    num = "" + num; //coerce num to be a string
    return !isNaN(num) && !isNaN(parseFloat(num));
}
Run Code Online (Sandbox Code Playgroud)

以下是一个很可能性能不佳但结果可靠的解决方案。这是一个由 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));
};
Run Code Online (Sandbox Code Playgroud)

不过,后一个版本有两个新变量。可以通过执行以下操作来解决其中之一:

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));
};
Run Code Online (Sandbox Code Playgroud)

除了手动测试我将遇到的少数用例之外,我还没有对其中的任何一个进行过太多测试,这些用例都是非常标准的东西。这是一种“站在巨人的肩膀上”的情况。


Siu*_*ear 6

引用:

isNaN(num) // 如果变量不包含有效数字,则返回 true

如果您需要检查前导/尾随空格,则不完全正确 - 例如,当需要一定数量的数字时,您需要获取“1111”而不是“111”或“111”作为可能的 PIN输入。

更好地使用:

var num = /^\d+$/.test(num)
Run Code Online (Sandbox Code Playgroud)


小智 6

也许有一两个人遇到这个问题需要比平常更严格的检查(就像我做的那样).在这种情况下,这可能是有用的:

if(str === String(Number(str))) {
  // it's a "perfectly formatted" number
}
Run Code Online (Sandbox Code Playgroud)

谨防!这将拒绝像琴弦.1,40.000,080,00.1.这是非常挑剔的 - 字符串必须匹配此测试通过的数字的" 最小完美形式 ".

它使用StringNumber构造函数将字符串转换为数字并再次返回,从而检查JavaScript引擎的"完美最小形式"(它与初始Number构造函数转换为的形式)是否与原始字符串匹配.

  • 谢谢@JoeRocc.我也需要这个,但只是为了整数,所以我补充说:`(str === String(Math.round(Number(str))))`. (2认同)

Abt*_*ian 6

当防止空字符串和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  
Run Code Online (Sandbox Code Playgroud)

当不防范空字符串时并且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 
Run Code Online (Sandbox Code Playgroud)

使用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
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 为了与解决原始问题保持一致,仅考虑字符串、空和未初始化的值。如果数组和对象是正在考虑的值,则存在其他边缘情况。
  • 二进制、八进制、十六进制和指数表示法中的字符不区分大小写(即:“0xFF”、“0XFF”、“0xfF”等在上面所示的测试用例中都会产生相同的结果)。
  • 与某些情况下的with Infinity(区分大小写)不同,以字符串格式作为测试用例传递给上述任何方法的 和 对象中的常量将被确定为不是数字NumberMath
  • 有关如何将参数转换为 a以及为什么存在 for 和空字符串的边缘情况的说明,请参阅此处Numbernull


J.P*_*vet 6

2019 年:实用且严格的数值有效性检查

通常,“有效数字”是指不包括 NaN 和无穷大的 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;
}
Run Code Online (Sandbox Code Playgroud)

并以这种方式使用它:

if (isReferringFiniteNumber(theirValue)) {
  myCheckedValue = Number(theirValue);
} else {
  console.warn('The provided value doesn\'t refer to a finite number');
}
Run Code Online (Sandbox Code Playgroud)


Emr*_*cel 6

这样对我有用。

function isNumeric(num){
    let value1 = num.toString();
    let value2 = parseFloat(num).toString();
    return (value1 === value2);
}
Run Code Online (Sandbox Code Playgroud)
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
)
Run Code Online (Sandbox Code Playgroud)


lig*_*t78 5

parseInt(),但要注意这个函数有点不同,例如它为parseInt("100px")返回100.

  • 因为你需要使用`paraseInt(09,10)` (10认同)
  • [从 ECMAScript 5 开始](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt#Octal_interpretations_with_no_radix),它具有 [广泛的浏览器支持](http://caniuse. com/#feat=es5) (IE≥9),你不再需要 `, 10` 参数。`parseInt('09')` 现在等于 9。 (2认同)

Gre*_*Woz 5

它对 TypeScript 无效,因为:

declare function isNaN(number: number): boolean;

对于打字稿,您可以使用:

/^\d+$/.test(key)