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

5 ответов

Решение

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

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

Номера 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, Поэтому вас может заинтересовать проверка десятичных чисел в JavaScript - IsNumeric()

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

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

Для пользователей 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))
    }
  />)

Это работает и на сафари.

Спасибо.

Я использую комбинацию разбора и проверки номеров.. как указано ниже

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

надеюсь это поможет

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

isNumber( new Number(123) )

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

Другие вопросы по тегам