如何检查 JavaScript 数字是不是是真实有效的数字?

Posted

技术标签:

【中文标题】如何检查 JavaScript 数字是不是是真实有效的数字?【英文标题】:How to check if a JavaScript number is a real, valid number?如何检查 JavaScript 数字是否是真实有效的数字? 【发布时间】:2012-01-21 11:48:13 【问题描述】:

我的代码是:

function isNumber(n)
return typeof n == 'number' && !isNaN(n);


window.onload=function()
var a=0,b=1,c=2.2,d=-3,e=-4.4,f=10/3;
var shouldBeTrue=[a,b,c,d,e,f];

var aa="0",bb="1",cc="2.2",dd="-3",ee="-4.4",ff="10/3";
var shouldBeFalse=[aa,bb,cc,dd,ee,ff];

var aaa,bbb=true,ccc=false,ddd=document.getElementsByTagName('html');
var alsoTheseBeFalse=[aaa,bbb,ccc,ddd,""," ",,null,NaN];

for(var i=0;i<shouldBeTrue.length;i++)
    if(isNumber(shouldBeTrue[i]) != true) alert("x");
for(i=0;i<shouldBeFalse.length;i++)
    if(isNumber(shouldBeFalse[i]) != false) alert("x");
for(i=0;i<alsoTheseBeFalse.length;i++)
    if(isNumber(alsoTheseBeFalse[i]) != false) alert("x");

我还应该检查什么以确保我的功能在所有方面都 101% 完美? (另外,如果你知道更好的功能请告诉我)

【问题讨论】:

您希望完善哪个功能?您可以从给变量起更有意义的名称开始... @frenchie:他说的是isNumber(n)函数。 有数字案例你没有检查,但我不能让你的函数中断(即:g=2E30,gg=0/0) @Brian,好吧 0/0=NaN(我确实检查过),但我对 '2E30' 的事情很好奇,因为它返回 true。你知道为什么它返回 true 吗? 旁注,在您的测试用例中,您使用的是!= false。这不是必需的,因为您的isNumber 函数总是返回一个布尔值(truefalse)。在if ( ... ) 中,表达式始终被视为布尔值。 if (isNumber(a) != false) 等价于if (isNumber(a) == true) 等价于if (isNumber(a)) 【参考方案1】:

如果你想检查一个数是否为实数,你还应该检查它是否是有限的:

function isNumber(n)
    return typeof n == 'number' && !isNaN(n) && isFinite(n);
 

另一种方法(解释如下):

function isNumber(n)
    return typeof n == 'number' && !isNaN(n - n);

更新:验证实数的两个表达式

由于 javascript 数字表示实数,相同数字的减法操作数应生成零值(additive identity)。超出范围的数字应该(并且将会)无效,NaN

1        - 1        = 0    // OK
Infinity - Infinity = NaN  // Expected
NaN      - NaN      = NaN  // Expected
NaN      - Infinity = NaN

【讨论】:

好吧,你的代码更大,多做 1 次操作。我会使用它的唯一方法是,如果你告诉我我当前的功能会失败而你的不会失败的方式 @TuxedoKnightChess 输入以下值:Infinity。它通过了前两个测试,虽然它不是一个有用的实数:isNumber(Infinity) 为您当前的函数返回 true。 var n=2E30; 的结果是什么? @TuxedoKnightChess:有一个非常简单的方法可以找出答案。 @TuxedoKnightChess 方法略有不同,但结果完全相同。【参考方案2】:

JS 编号可以是以下值:

有限的数字 +Infinity-Infinity NaN

然后还有可以强制转换为数字的非数字值,例如编号对象。您可能希望将它们视为数字。

如果您只想测试有限数,只需使用Number.isFinite

Number.isFinite(value)

var isNumber = Number.isFinite;
assert('isNumber(1)', true);
assert('isNumber(1.1)', true);
assert('isNumber(+0)', true);
assert('isNumber(-0)', true);
assert('isNumber(-1.1)', true);
assert('isNumber(Math.PI)', true);
assert('isNumber(1e300)', true);
assert('isNumber(+Infinity)', false);
assert('isNumber(-Infinity)', false);
assert('isNumber(NaN)', false);
assert('isNumber(null)', false);
assert('isNumber(undefined)', false);
assert('isNumber(true)', false);
assert('isNumber(false)', false);
assert('isNumber("123")', false);
assert('isNumber("foo")', false);
assert('isNumber(new Number(1))', false);
assert('isNumber([])', false);
assert('isNumber()', false);
assert('isNumber(function())', false);
function assert(code, expected) 
  var result = eval(code);
  console.log('Test ' + (result===expected ? 'pass' : 'FAIL') + ': ', code, ' -> ', result);

如果要包含无穷大,请检查类型并排除 NaN

typeof value === "number" && !Number.isNaN(value)

function isNumber(value) 
  return typeof value === "number" && !Number.isNaN(value);

assert('isNumber(1)', true);
assert('isNumber(1.1)', true);
assert('isNumber(+0)', true);
assert('isNumber(-0)', true);
assert('isNumber(-1.1)', true);
assert('isNumber(Math.PI)', true);
assert('isNumber(1e300)', true);
assert('isNumber(+Infinity)', true);
assert('isNumber(-Infinity)', true);
assert('isNumber(NaN)', false);
assert('isNumber(null)', false);
assert('isNumber(undefined)', false);
assert('isNumber(true)', false);
assert('isNumber(false)', false);
assert('isNumber("123")', false);
assert('isNumber("foo")', false);
assert('isNumber(new Number(1))', false);
assert('isNumber([])', false);
assert('isNumber()', false);
assert('isNumber(function())', false);
function assert(code, expected) 
  var result = eval(code);
  console.log('Test ' + (result===expected ? 'pass' : 'FAIL') + ': ', code, ' -> ', result);

如果您想将数字对象视为数字,您可以使用

value = Number.valueOf.call(value); // throws if value was not a number object

function isNumber(value) 
  try  value = Number.prototype.valueOf.call(value);  catch(err)  
  return Number.isFinite(value);

assert('isNumber(1)', true);
assert('isNumber(1.1)', true);
assert('isNumber(+0)', true);
assert('isNumber(-0)', true);
assert('isNumber(-1.1)', true);
assert('isNumber(Math.PI)', true);
assert('isNumber(1e300)', true);
assert('isNumber(+Infinity)', false);
assert('isNumber(-Infinity)', false);
assert('isNumber(NaN)', false);
assert('isNumber(null)', false);
assert('isNumber(undefined)', false);
assert('isNumber(true)', false);
assert('isNumber(false)', false);
assert('isNumber("123")', false);
assert('isNumber("foo")', false);
assert('isNumber(new Number(1))', true);
assert('isNumber([])', false);
assert('isNumber()', false);
assert('isNumber(function())', false);
function assert(code, expected) 
  var result = eval(code);
  console.log('Test ' + (result===expected ? 'pass' : 'FAIL') + ': ', code, ' -> ', result);

如果要包含可强制为数字的任意值,可以使用一元 + 进行强制。

value = +value; // throws if value was not number-coercible

还有isNaN 函数(不要与Number.isNaN 混淆),它会先强制然后与NaN 比较。但请注意空格字符串和null 被强制转换为+0,而不是NaN。所以你可能对Validate decimal numbers in JavaScript - IsNumeric()感兴趣

【讨论】:

【参考方案3】:

这取决于您希望将什么视为数字。您的代码将 Infinity 和 -Infinity 分类为数字。如果您不希望这样,请将 !isNaN(n) 替换为 isFinite(n)。

由于类型检查,您的代码将“42”(字符串文字)分类为不是数字;但我认为这是故意的。

【讨论】:

【参考方案4】:

我使用解析和检查数字的组合......如下所述

function isNumber(inputValue) return ((parseFloat(inputValue) ==0 || parseFloat(inputValue)) && !isNaN(inputValue)); ;

希望对你有帮助

【讨论】:

【参考方案5】:

对于 react 或其他框架用户,可能的解决方案是:

const  onChange, value  = this.props;
return (
  <input
    type="text" // Note: I have kept this as text
    value=typeof value !== 'number' || isNaN(value) ? '' : value
    className=classnames('input')
    onChange=(event) =>
      onChange &&
      onChange(parseFloat(event.target.value))
    
  />)

这也适用于野生动物园。

谢谢。

【讨论】:

【参考方案6】:

如果您将其对象包装器中的数字视为数字,那么它将失败:

isNumber( new Number(123) )

由于投反对票者有一些无法通过简单测试缓解的理解问题,new Number(123) 将从typeof 测试返回'object',因此不会通过。

【讨论】:

@down-voter:给出一个理由。请告诉我new Number(123) 将如何通过问题中的isNumber 测试。 我没有投反对票,但是您的代码仅显示了破坏代码的示例,而没有提出解决方案。 OP没有问如何打破功能,而是如何改进功能。

以上是关于如何检查 JavaScript 数字是不是是真实有效的数字?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JavaScript 中检查字符串是不是包含数字和特殊字符?

JavaScript - 如何检查是不是在数字输入字段中输入了字母字符或符号[重复]

检查输入字符串是不是包含javascript中的数字

如何检查字符串是不是至少包含一个数字、字母和既不是数字也不是字母的字符?

如何检查布尔值是真还是假?

如何检查一个数字是不是为负数?