Как проверить, является ли номер JavaScript реальным, действительным номером?

МОЙ код:

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% идеальна во всех отношениях? (также, если вы знаете лучшую функцию, пожалуйста, скажите мне)

Ответ 1

Если вы хотите проверить, является ли число реальным числом, вы также должны проверить, является ли оно конечным:

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

Другой метод (объяснение ниже):

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

Обновление: два выражения для проверки действительного числа

Так как числа JavaScript представляют действительные числа, то операнд деления на том же самом номере должен давать нулевое значение (аддитивный идентификатор). Номера за пределами диапазона должны (и будут) недействительными, NaN.

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

Ответ 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);
}

Ответ 3

Это зависит от того, что вы хотите рассматривать как число. Ваш код классифицирует Infinity и -Infinity как числа. Если вы этого не хотите, замените! IsNaN (n) на isFinite (n).

И ваш код классифицирует "42" (строковый литерал) как не число, из-за проверки типа; но я предполагал, что это намеренно.

Ответ 4

Если вы считаете число в своей обертке объекта числом, то оно будет терпеть неудачу:

isNumber( new Number(123) )

Так как у downvoter есть некоторые проблемы с пониманием, которые не могут быть смягчены простым тестом, new Number(123) вернет 'object' из теста typeof и, как таковой, не пройдет.