如何检查JavaScript编号是否真实有效?

时间:2011-12-15 20:04:33

标签: javascript numbers int

我的代码是:

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%? (另外,如果你知道更好的功能,请告诉我)

6 个答案:

答案 0 :(得分:18)

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

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 :(得分:1)

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

感兴趣

答案 2 :(得分:0)

这取决于你想要的数字。您的代码将Infinity和-Infinity分类为数字。如果您不想这样,请用isFinite(n)替换!isNaN(n)。

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

答案 3 :(得分:0)

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

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

希望这会有所帮助

答案 4 :(得分:0)

对于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))
    }
  />)

这也适用于野生动物园。

谢谢。

答案 5 :(得分:-1)

如果您将其对象包装器中的数字视为数字,则它将失败并显示:

isNumber( new Number(123) )

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