如何检查字符串是否为有效数字?

How can I check if a string is a valid number?

提问人:Electrons_Ahoy 提问时间:10/7/2008 最后编辑:LiamElectrons_Ahoy 更新时间:5/4/2023 访问量:1622335

问:

我希望在与旧的 VB6 函数相同的概念空间中有什么东西?IsNumeric()

JavaScript 验证 数字

评论

5赞 Michael Haren 10/7/2008
请参阅我前段时间问过的这个相关问题
55赞 Joel Coehoorn 10/7/2008
如果您要回答这个问题,请尝试跳过所有正则表达式答案。那不是办法。
18赞 SasQ 5/19/2014
除非有人想这样做:检查给定的字符串是否具有有效数字流的格式。那为什么会错呢?
41赞 Andrew 10/6/2017
所选答案不正确!!查看其注释,但基本上它失败了,例如,,,等。它返回这些,暗示它们是数字。isNaN("")isNaN(" ")isNaN(false)false
11赞 vir us 5/9/2020
所以选择的答案是不正确的,正则表达式也不是这样做的方法。那么哪一个是正确的呢?

答:

31赞 theraccoonbear 10/7/2008 #1

尝试 isNan 函数

isNaN() 函数确定值是否为非法数字 (Not-a-Number)。

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

此函数不同于特定于 Number 的 Number.isNaN() 方法。

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

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

评论

4赞 Michael Haren 10/7/2008
确保为空字符串添加勾选。isNaN('') 返回 false,但在这种情况下您可能希望它返回 true。
3赞 JonnyRaa 1/20/2015
isFinite 是一个更好的检查 - 它处理 Infinity 的奇怪极端情况
4赞 Michael 3/3/2016
@MichaelHaren 不够好! 返回仅包含空格字符的任何字符串,包括“\u00A0”之类的内容。isNaN()false
5赞 Krisztián Balla 7/27/2017
警告:不适用于以下值:null、“”(空字符串)和 false。
0赞 Dan Dascalescu 10/6/2019
我意识到这个答案是在 11 年前给出的,比接受的答案早几分钟,但不管你喜欢与否,被接受的答案围绕它有更多的对话,所以这个答案并没有真正为回答问题增加任何东西。我恳请删除它,以避免分散新读者的注意力。我还认为,如果你这样做,你会得到纪律处分徽章。
6赞 liggett78 10/7/2008 #2

parseInt(),但请注意,这个函数在某种意义上有点不同,例如它为 parseInt(“100px”) 返回 100。

评论

0赞 djechlin 6/26/2013
和 11 表示 .parseInt(09)
12赞 Gavin 6/28/2014
因为你需要使用paraseInt(09, 10)
2赞 Rory O'Kane 10/3/2017
从具有广泛浏览器支持 (IE≥9) 的 ECMAScript 5 开始,您不再需要该参数。 现在等于 9。, 10parseInt('09')
77赞 roenving 10/7/2008 #3

你可以采用正则表达式的方式:

var num = "987238";

if(num.match(/^-?\d+$/)){
  //valid integer (positive or negative)
}else if(num.match(/^\d+\.\d+$/)){
  //valid float
}else{
  //not valid number
}

评论

54赞 Joel Coehoorn 10/7/2008
在本例中,RegExp == bad
11赞 Ori 4/18/2012
这在十六进制数(例如0x12)、没有前导零(例如 .42)和负数时失败。
23赞 computrius 12/31/2014
@JoelCoehoorn 想详细说明一下为什么 RegExp == 在这里很糟糕?对我来说似乎是一个有效的用例。
7赞 Joel Coehoorn 12/31/2014
构建数字的方法比看起来要多(另一条评论中的十六进制数字只是一个例子),并且有许多数字可能被认为无效(溢出类型、太精确等)。此外,正则表达式比仅使用内置机制更慢、更复杂
2赞 Joseph Merdrignac 10/31/2017
也应该与科学记数法相匹配......1e10 等
3170赞 Dan 10/7/2008 #4

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.

请记住,与 不同,(顾名思义)将通过砍掉小数点后的所有内容将浮点数转换为整数(如果您因为这种行为而想使用,最好使用另一种方法):+numparseIntparseInt()

+'12.345'          // 12.345
parseInt(12.345)   // 12
parseInt('12.345') // 12

空字符串

空字符串可能有点违反直觉。 将空字符串或带空格的字符串转换为零,并假定相同:+numisNaN()

+''                // 0
+'   '             // 0
isNaN('')          // false
isNaN('   ')       // false

但不同意:parseInt()

parseInt('')       // NaN
parseInt('   ')    // NaN

评论

176赞 Adam Raney 4/29/2009
关于 parseInt 的一个非常重要的注意事项是,它允许您指定用于将字符串转换为 int 的基数。这是一个很大的问题,因为如果您不提供它,它会尝试为您猜测基数。因此,例如:parseInt(“17”) 得到 17(十进制,10),但 parseInt(“08”) 得到 0(八进制,8)。因此,除非您另有打算,否则最安全的做法是使用 parseInt(number, 10),显式指定 10 作为基数。
49赞 David Hellsing 11/6/2010
请注意,!isNaN(undefined) 返回 false。
172赞 EML 12/30/2013
这完全是错误的——它是如何获得这么多赞成票的?不能使用“检查变量是否不是数字”。“不是数字”与“IEEE-794 NaN”不同,后者是测试的。特别是,至少在测试布尔值和空字符串时,这种用法会失败。请参阅 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...isNaNisNaN
72赞 Kevin Jurkowski 1/22/2014
检查某物是否为数字的最快方法是“等于自我”检查:在最新版本的 Chrome 中,它比 isNaN 快 ~3994%。请参阅此处的性能测试:jsperf.com/isnan-vs-typeof/5var n = 'a'; if (+n === +n) { // is number }
32赞 keithpjolley 5/31/2017
**警告**这个答案是错误的。使用风险自负。例:isNaN(1 + false + parseInt("1.do you trust your users?"))
5赞 Siubear 6/1/2012 #5

报价:

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

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

更好用:

var num = /^\d+$/.test(num)

评论

0赞 Rudey 2/23/2017
值 和 all 都返回 false。此外,大于正无穷大或小于负无穷大的值返回 true,而它们可能应返回 false。'-1''0.1''1e10'
18赞 mark 10/2/2013 #6

老问题,但给出的答案中缺少几点。

科学记数法。

!isNaN('1e+30')是 ,但是在大多数情况下,当人们询问数字时,他们不想匹配 .true1e+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
>

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

无限

> typeof Infinity
'number'
> !isNaN('Infinity')
true
> isFinite('Infinity')
false
>

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

  • 非科学记数法
  • 可预测的转换NumberString
  • 有限的

这不是一件容易的事。这是一个简单的版本:

  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);
  }

然而,即使是这个也远未完成。这里不处理前导零,但它们确实搞砸了长度测试。

评论

2赞 Dan Jones 1/5/2017
“然而,在大多数情况下,当人们要求数字时,他们不想匹配 1e+30 之类的东西”你为什么这么说?如果有人想知道一个字符串是否包含一个数字,在我看来,他们会想知道它是否包含一个数字,而 1e+30 是一个数字。当然,如果我在 JavaScript 中测试字符串的数值,我希望它匹配。
2赞 Predhin 4/30/2014 #7

PFB工作解决方案:

 function(check){ 
    check = check + "";
    var isNumber =   check.trim().length>0? !isNaN(check):false;
    return isNumber;
    }
199赞 Gavin 6/28/2014 #8

如果你只是想检查一个字符串是否是一个整数(没有小数位),正则表达式是一个不错的方法。其他方法对于如此简单的事情来说太复杂了。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

评论

15赞 yongnan 11/13/2014
控制台.log(isNumeric('-1'));
8赞 Gaël Barbin 3/2/2015
控制台.log(isNumeric('2e2'));
34赞 gus3001 10/10/2017
也许只是将“isNumeric”重命名为“hasOnlyDigits”。在许多情况下,这正是您正在寻找的支票。
2赞 pmiguelpinto90 9/20/2019
这就是我一直在寻找的,相当于php ctype_digit
8赞 Devin Rhode 10/20/2020
稍微好一点..禁止使用阿拉伯语等语言的数字字符/^[0-9]+$/.test(value)
12赞 GibboK 3/13/2015 #9

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

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

注意:注意传递空字符串或和 as Number 时将返回 0;传递 true 将返回 1,false 返回 0。'\t\t''\n\t'

    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

评论

0赞 GregRos 12/29/2018
构造函数与 完全相同。Number+x
0赞 zurfyx 1/21/2020
顺便说一句,请记住,ES6 也处理浮点数,就像不是一样Number()Number.parseFloat()Number.parseInt()
54赞 Michael 3/3/2016 #10

如果你真的想确保一个字符串只包含一个数字、任何数字(整数或浮点数)和一个数字,你不能使用 / 、 或单独使用。请注意,实际上是返回 何时返回一个数字,以及何时返回 ,因此我将将其排除在讨论的其余部分之外。parseInt()parseFloat()Number()!isNaN()!isNaN()trueNumber()falseNaN

问题在于,如果字符串包含任何数字,它将返回一个数字,即使该字符串不包含一个数字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 识别的浮点数,否则您将错过案例或识别不应该识别的案例。即使您可以推出自己的正则表达式,为什么?有更简单的内置方法可以做到这一点。

然而,事实证明,(和)在不应该返回数字时返回数字的每种情况下都是正确的,反之亦然。因此,要确定字符串是否真的是确切的,并且只是一个数字,请调用这两个函数并查看它们是否返回 true:Number()isNaN()parseFloat()

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))
}

评论

2赞 Rudey 2/23/2017
当字符串具有前导空格或尾随空格时,这将返回 true。,并且都返回 true。' 1''2 '' 3 '
0赞 Ultroman the Tacoman 5/15/2017
在 return-statement 中添加这样的东西可以解决这个问题: && !/^\s+|\s+$/g.test(str)
2赞 Ian 11/4/2017
@RuudLenders - 大多数人不会在乎是否有尾随空格被丢弃以使字符串成为有效数字,因为在许多接口中很容易不小心放入额外的空格。
9赞 Rudey 11/5/2017
如果数字字符串来自用户输入,则确实如此。但我认为无论如何我都应该提到空格,因为我认为大多数需要函数的人都不是在处理用户界面。此外,一个好的数字输入不允许以空格开头。isNumber
1赞 Alexander Hunter 5/20/2023
@Michael 非常感谢你的这篇文章。当我涉足 JavaScript 时,我发现它非常有帮助。在学术领域,这不是一个实际问题,字符串“Infinity”由上述函数返回为数字(true),这是有道理的,因为Infinity在Javascript中是一个数字:-)。Numeric() 和 parseFloat 都将字符串转换为无穷大。谢谢,和平。
3赞 The Dembinski 1/4/2017 #11

如果有人走到这一步,我花了一些时间试图修补这个时刻.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

欢迎任何建议。:]

评论

2赞 Alex Cory 1/31/2017
和呢?isNumeric(' ')isNumeric('')
0赞 frankenapps 1/16/2018
为了解决上述问题,我想补充一点,我自己也有一个问题。&& (val.replace(/\s/g,'') !== '') //Empty && (val.slice(-1) !== '.') //Decimal without Number
10赞 user993683 1/9/2017 #12

也许有一两个人遇到这个问题,他们需要比平时更严格的检查(就像我一样)。在这种情况下,这可能很有用:

if(str === String(Number(str))) {
  // it's a "perfectly formatted" number
}

小心!这将拒绝像 、 、 、 这样的字符串。这是非常挑剔的 - 字符串必须与数字的“最小完美形式”匹配,才能通过此测试。.140.00008000.1

它使用 and 构造函数将字符串转换为一个数字,然后再转换回来,从而检查 JavaScript 引擎的“完美最小形式”(它通过初始构造函数转换为的格式)是否与原始字符串匹配。StringNumberNumber

评论

2赞 keithpjolley 5/31/2017
谢谢@JoeRocc。我也需要这个,但只是为了整数,所以我添加了:.(str === String(Math.round(Number(str))))
0赞 GregRos 12/29/2018
请注意,,并通过此测试。但是,这可以通过额外的测试来解决。"Infinity""-Infinity""NaN"Number.isFinite
1赞 GregRos 12/29/2018
这与 完全相同。它基本上检查字符串是否是字符串化 JS 编号的结果。知道了这一点,我们还可以看到一个问题:测试通过了,但失败了,这是当通过时。对于非常大的数字也是如此。str === ("" + +str)0.0000010.00000011e-7
0赞 Ben Aston 10/2/2020
这个答案是不正确的。 是“完全有效和格式化”,但此算法失败。1e10
16赞 JohnP2 2/21/2017 #13

我已经测试过了,迈克尔的解决方案是最好的。在上面为他的答案投票(在此页面搜索“如果你真的想确保一个字符串”以找到它)。从本质上讲,他的答案是这样的:

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、[](还有其他?

评论

1赞 Ultroman the Tacoman 5/15/2017
对于尾随/前导空格,这仍然返回 true。在 return-statement 中添加这样的东西可以解决这个问题: && !/^\s+|\s+$/g.test(str)
2赞 JohnP2 6/15/2017
所以“123”应该是假的,而不是数字,而“1234”应该是数字吗?我喜欢它的样子,所以“123”是一个数字,但如果前导或尾随空格应该改变值,这可能取决于开发人员的自由裁量权。
7赞 Ultroman the Tacoman 5/15/2017 #14

为什么jQuery的实现不够好?

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

迈克尔提出了这样的建议(尽管我在这里窃取了“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));
};

我没有测试过其中任何一个,除了手动测试我当前困境中将遇到的几个用例之外,其他方式都是非常标准的东西。这是一种“站在巨人肩膀上”的情况。

7赞 Simon_Weaver 6/27/2018 #15

我喜欢这个的简单性。

Number.isNaN(Number(value))

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

打字稿打字板

警告:请参阅下面的 Jeremy 评论。这在某些值上存在一些问题,我现在没有时间修复它,但是使用打字稿 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;
}

假设您有一个属性,它是 .您可能希望根据它是否是字符串来执行逻辑。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;    
}

typeguard 足够智能,可以将语句中的类型限制为 ONLY 。这允许编译器允许,如果类型是 ,则不允许 。widthifstringwidth.endsWith(...)string | number

你可以随心所欲地称呼 typeguard,,,但我认为它有点模棱两可且难以阅读。isNotNumberisNumberisStringisNotStringisString

评论

2赞 Jeremy 10/26/2019
在普通 JS 中工作得相对较好,但失败了 、 、 等情况,更重要的是失败了 和 。不确定您的 TS 是否弥补了它,但看起来如果您通过了或尝试失败,它不会崩溃但会返回。1..11,1-32.1.12undefinedNaNundefinedNaNundefined * 2NaN
0赞 yoel halb 4/7/2022
请注意,这种方法允许在数字中有一个 or(例如),因为它被认为是一个有效的数字(“科学记数法”),但不一定是你想要的......eE2E34
3赞 Travis Parks 10/9/2018 #16

我最近写了一篇关于如何确保变量是有效数字的文章: https://github.com/jehugaleahsa/artifacts/blob/master/2018/typescript_num_hack.md 这篇文章解释了如何确保浮点数或整数,如果这很重要的话( vs )。+x~~x

本文假设变量以 a 或 a 开头,并且是可用/polyfilled。将其扩展到处理其他类型的内容也不难。这是它的精髓:stringnumbertrim

// 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
}
85赞 Hamzeen Hameem 10/25/2018 #17

这个问题的公认答案有很多缺陷(正如其他几个用户所强调的那样)。这是在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

评论

8赞 Ben Aston 10/2/2020
parseFloat对于此应用程序来说是不够的,因为当它遇到第一个无法解析为数字的字符时,它将返回到目前为止解析的有效数字。例如。.parseFloat('1.1ea10') === 1.1
2赞 Yohan Dahmani 7/2/2021
请注意,如果您使用 Number.isNan 和 Number.isFinite,这将不起作用。
0赞 Cas 7/27/2021
对于字符串,并且不起作用,因为它们不会将字符串转换为数字。Number.isNaNNumber.isFinite
0赞 Rossof Rostislav 10/30/2022
10,1怎么样?
0赞 dazzafact 3/27/2023
这不适用于数组输入 isNumeric([2])。Arraytype 不是数字
2赞 cdeutsch 12/21/2018 #18

省去试图寻找“内置”解决方案的麻烦。

没有一个好的答案,这个线程中大量投票的答案是错误的。

npm install is-number

在 JavaScript 中,可靠地检查值是否为数字并不总是那么简单。开发人员通常使用 +、- 或 Number() 将字符串值转换为数字(例如,当从用户输入、正则表达式匹配、解析器等返回值时)。但是,有许多非直观的边缘情况会产生意想不到的结果:

console.log(+[]); //=> 0
console.log(+''); //=> 0
console.log(+'   '); //=> 0
console.log(typeof NaN); //=> 'number'
3赞 gvlax 1/30/2019 #19
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 ...
}
5赞 Abtin Gramian 3/17/2019 #20

当防止空字符串和 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  

当 NOT 防止空字符串和 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(区分大小写)不同,在某些情况下,作为测试用例以字符串格式传递给上述任何方法的 NumberMath 对象中的常量将被确定为不是数字。
  • 有关如何将参数转换为 Number 以及为什么存在 null 和空字符串的边缘情况的说明,请参阅此处

评论

0赞 Philip 3/14/2020
另请参阅 stackoverflow.com/questions/46677774/...
0赞 gman 1/12/2021
失败 、 和""nullundefined
0赞 Abtin Gramian 1/16/2021
@gman感谢您指出边缘情况。我更新了答案以解决您提到的问题以及 .它看起来也已经正确处理,但我明确添加了它以使其清楚。Infinity"Infinity"undefined
6赞 Greg Wozniak 5/23/2019 #21

它对 TypeScript 无效,因为:

declare function isNaN(number: number): boolean;

对于 TypeScript,您可以使用:

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

评论

0赞 John Montgomery 7/14/2020
/^\d+$/.test("-1") // false要在 TS 中使用非数字,只需将值转换为 ,或者使用此处使用其他更全面的解决方案之一,这些解决方案使用 、 等。isNaNanyNumberparseFloat
36赞 Jeremy 10/25/2019 #22

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

也许这已经被重提了太多次了,但是我今天也和这个打过架,想发布我的答案,因为我没有看到任何其他答案可以如此简单或彻底地做到这一点:

ES3系列

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

DSW的

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);

您还可以尝试自己的功能,并在这些用例中刚刚过去,并扫描所有用例的“true”。isNumeric

或者,要查看每个返回的值,请执行以下操作:

Results of each test against <code>isNumeric()</code>

评论

1赞 S.Serpooshan 3/9/2021
好,除了“0x10”(返回 true!
1赞 Jeremy 4/27/2021
@S.Serpooshan,0x10应该返回 true,它是一个十六进制数。0x1 显示在测试用例中,并且预期返回 true,它是一个数字。如果您的特定用例需要将十六进制数字视为字符串,那么您将需要以不同的方式编写解决方案。
0赞 S.Serpooshan 4/29/2021
是的,这取决于我们的情况
2赞 Kieran101 8/23/2022
也适用于科学记数法:isNumeric('3e2') / isNumeric(3e2)
3赞 Milan 2/24/2023
打字稿版本的类型应为未知:const isNumeric = (num: unknown)
7赞 J.P. Duvet 11/14/2019 #23

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');
}
4赞 Zoman 4/2/2020 #24

这是建立在前面的一些答案和评论之上的。它涵盖了所有边缘情况,还可以选择处理科学记数法:

const NUMBER_REG_EXP = /^-?\d+(?:\.\d+)?$/;
const SCIENTIFIC_NOTATION_REG_EXP = /^-?\d+(?:\.\d+)?(?:[eE]\d+)?$/;

const isNumeric = (n, allowScientificNotation = false) => (
    (typeof n === 'number' && !Number.isNaN(n)) || 
    (typeof n === 'string' && (allowScientificNotation ?
        SCIENTIFIC_NOTATION_REG_EXP : NUMBER_REG_EXP).test(n))
);
2赞 dsmith63 4/9/2020 #25

这似乎抓住了看似无限数量的边缘情况:

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;
};
3赞 lebobbi 10/20/2020 #26

因此,这将取决于您希望它处理的测试用例。

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

截至今天,所有其他答案似乎都未能通过其中一个测试用例。

评论

1赞 epan 6/18/2021
请注意,如果对您很重要,请返回isNumeric('007')true
30赞 Hasan Nahiyan Nobel 8/18/2021 #27

TL的;博士

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

内置函数之间的比较

由于没有一个现有的资源让我的灵魂满意,我试图弄清楚这些功能到底发生了什么。

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

  1. !isNaN(input)(它给出的输出与+input === +input)
  2. !isNaN(parseFloat(input))
  3. isFinite(input)

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

我在几个案例中测试了这些函数,并以 markdown 的形式生成输出。这是它的样子:

input !isNaN(input)
+input===+input
!isNaN(
parseFloat(
input))
isFinite(
input)
评论
123 ✔️ ✔️ ✔️ -
'123' ✔️ ✔️ ✔️ -
12.3 ✔️ ✔️ ✔️ -
'12.3' ✔️ ✔️ ✔️ -
'   12.3   ' ✔️ ✔️ ✔️ 空空格已修剪,如预期的那样。
1_000_000 ✔️ ✔️ ✔️ 数字分隔符理解,也是意料之中的。
'1_000_000' ✔️ 惊喜!JS 只是不会解析字符串中的数字分隔符。有关详细信息,请查看问题。(为什么解析为浮点数有效?好吧,它没有。😉)
'0b11111111' ✔️ ✔️ ✔️ 二进制形式理解了,因为它应该理解。
'0o377' ✔️ ✔️ ✔️ 八进制形式也理解。
“0xFF” ✔️ ✔️ ✔️ 当然,十六进制是可以理解的。有人不这么认为吗?😒
'' ✔️ ✔️ 空字符串应该是一个数字吗?
'    ' ✔️ ✔️ 仅空格字符串应该是一个数字吗?
“ABC” 每个人都同意,而不是一个数字。
'12.34Ab!@#$' ✔️ 啊!现在,这是可以理解的。对我来说并不令人印象深刻,但在某些情况下可能会派上用场。parseFloat()
'10e100' ✔️ ✔️ ✔️ 10100确实是一个数字。
但要小心!它比最大安全整数值 253(约 9×1015)大得多。有关详细信息,请阅读此内容
'10e1000' ✔️ ✔️ 跟我说,救命!
虽然并不像看起来那么疯狂。在 JavaScript 中,大于 ~10308 的值四舍五入为无穷大,这就是原因。详情请看这里
是的,将无穷大视为一个数字,并将无穷大解析为无穷大。
isNaN()parseFloat()
✔️ ✔️ 现在这很尴尬。在 JS 中,当需要转换时,null 变为零,我们得到一个有限数。
那为什么要在这里返回一个呢?有人请向我解释这个设计概念。
parseFloat(null)NaN
定义 不出所料。
无限 ✔️ ✔️ 如前所述,将无穷大视为一个数字,并将无穷大解析为无穷大。isNaN()parseFloat()

所以。。。哪一个是“正确的”?

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

同样,也许我们会从需要 10 100000000000 被视为有效数字时获得一点帮助(尽管问题仍然存在——为什么会这样,我们将如何处理)!isNaN()

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

就像我的情况一样,我完全需要 的输出,除了 null 大小写、空字符串大小写和仅空格字符串大小写。此外,我对非常庞大的数字并不感到头疼。所以我的代码看起来像这样:isFinite()

/**
 * 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(`  `, `&nbsp;&nbsp;`);

// Print markdown to console
console.log(markdownOutput);

评论

1赞 ooo 12/26/2022
以及更严格的解决方案
0赞 Brad 3/16/2023
很好的答案。荣誉。
0赞 MrYellow 4/19/2023
'0123'一个字符串,它应该保持一个字符串,但这些技术中的任何一种都会检测到一个数字,并会导致丢失。0
5赞 Emrah Tuncel 11/21/2021 #28

这样它对我有用。

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
)
17赞 chickens 12/19/2021 #29

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

一个衬里是整数:

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

一个衬里是数字:接受整数和小数

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

评论

0赞 yoel halb 4/7/2022
这有一个问题,即将空格视为无效字符,如果这不是您想要的,那么宁愿使用 或const isInteger = num => /^\s*-?[0-9]+\s*$/.test(num+'');const isNumeric = num => /^\s*-?[0-9]+(?:\.[0-9]+)\s*?$/.test(num+'');
2赞 chickens 4/7/2022
@yoelhalb 空格是数字的无效字符。您可以在传入字符串之前对其进行修剪。
0赞 windmaomao 10/12/2022
空字符串不是数字。但我想这是真的;)
0赞 R. Agnese 4/27/2023
这也没有考虑其他格式化数字的方法,例如十六进制数和科学记数法。
25赞 Musaib Mushtaq 6/27/2022 #30

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)

评论

6赞 Harry 10/8/2022
isFinite(null) 返回 true!
1赞 danefondo 11/13/2022
@Harry,根据 Mozilla Docs 的说法,使用 Number.isFinite(null) 会更健壮,并且会返回 false。缺点是如果你想接受'0',因为这也会返回false。似乎最好先拒绝 null,然后如果想使用它,请使用 isFinite。
1赞 Alice Chan 4/24/2023
还要注意 isFinite([]) 和 isFinite('') 返回 true