如何检查 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
函数总是返回一个布尔值(true
或false
)。在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 - 如何检查是不是在数字输入字段中输入了字母字符或符号[重复]