Как проверить, является ли число NaN в JavaScript?


415

Я пробовал это только в консоли JavaScript Firefox, но ни одно из следующих утверждений не возвращает true:

parseFloat('geoff') == NaN;

parseFloat('geoff') == Number.NaN;

5
Стоит прочесть, если ваша настоящая цель - проверить цифры: stackoverflow.com/questions/18082/…
Пол


1
@ Gothdo: конечно, но я спрашивал, как проверить, является ли число NaN, в отличие от любого значения.
Пол Д. Уэйт,

3
@ PaulD.Waite Да, но многие люди приходят сюда, когда гуглят что-то вроде «как проверить, является ли переменная nan в javascript».
Михал Перлаковский

PaulD.Waite Я согласен с вами, но у меня такая же проблема, как и у @Gothdo. Многие люди задаются этим вопросом с намерением «Как проверить, является ли значение в JS значением NaN». Вы можете проверить комментарий mjohnsonengr на тот же ответ . Кстати, я тоже отметил этот вопрос на внимание модераторов.
Допедуд

Ответы:


582

Попробуйте этот код:

isNaN(parseFloat("geoff"))

Для проверки, является ли какое-либо значение NaN, а не просто числами, смотрите здесь: Как вы проверяете NaN в Javascript?


8
Есть ли необходимость в paseFloat?
Рахул

23
Если вы хотите, чтобы пустая строка интерпретировалась как NaN, тогда да. (Я не говорю, что вы всегда будете.)
Пол Д. Уэйт

1
Если бы я был тобой, я бы присвоил его переменной и использовал переменную условия! == переменная. Как указано
allseded

3
isNaN(parseFloat("geoff")) // true isNaN(parseFloat("10geo")) // false Как это полезно?
Прашант

Это также может быть полезно, чтобы попробовать w3schools.com/jsref/jsref_isnan.asp
Сриджан Чаудхари

146

Я только что столкнулся с этой техникой в ​​книге « Эффективный JavaScript», которая довольно проста:

Поскольку NaN является единственным значением JavaScript, которое рассматривается как неравное для себя, вы всегда можете проверить, является ли значение NaN, проверив его на равенство с самим собой:

var a = NaN;
a !== a; // true 

var b = "foo";
b !== b; // false 

var c = undefined; 
c !== c; // false

var d = {};
d !== d; // false

var e = { valueOf: "foo" }; 
e !== e; // false

Не осознавал этого, пока @allsyed не прокомментировал, но это в спецификации ECMA: https://tc39.github.io/ecma262/#sec-isnan-number


27
Эффективно, но нелогично. Я не хотел бы поддерживать такой код.
Оса

35
Это не код, который противоречит интуиции, это NaN.
Джаззи

20
@DanM Это не ошибка, это стандартное поведение IEE754 NaN. Это то, как это реализовано в процессорах, и это ожидаемое поведение на каждом языке программирования в мире, который использует плавающие числа.
Тармил

4
@ Тармил должным образом отметил! Это на самом деле действительно интересно; Я всегда думал, что странность неравенства NaN - это вещь Javascript.
Дан М

2
NaN === Нан; // ложный. Это известная ошибка в JavaScript. isNan это новый метод.
atilkan

52

Используйте этот код:

isNaN('geoff');

Смотрите isNaN()документы по MDN .

alert ( isNaN('abcd'));  // alerts true
alert ( isNaN('2.0'));  // alerts false
alert ( isNaN(2.0));  // alerts false

1
Может быть, это только я, но идея NaN сбивает с толку, когда var value = 0/0;и var value2= String("123 131");создавать значения NaN, и что-то вроде этого var value3 = "abcd";также является значением NaN.
Ник Пинеда

@NickPineda Почему?
Синджай

44

Поскольку значение типа Number должно быть проверено, является ли оно NaNили нет, глобальная функция isNaNбудет делать работу

isNaN(any-Number);

Для общего подхода, который работает для всех типов в JS, мы можем использовать любое из следующего:

Для пользователей ECMAScript-5:

#1
if(x !== x) {
    console.info('x is NaN.');
}
else {
    console.info('x is NOT a NaN.');
}

Для людей, использующих ECMAScript-6:

#2
Number.isNaN(x);

И в целях обеспечения согласованности в ECMAScript 5 и 6, мы также можем использовать этот polyfill для Number.isNan

#3
//Polyfill from MDN
Number.isNaN = Number.isNaN || function(value) {
    return typeof value === "number" && isNaN(value);
}
// Or
Number.isNaN = Number.isNaN || function(value) {     
    return value !== value;
}

пожалуйста, проверьте этот ответ для более подробной информации.


6
Спасибо за то, что вы не просто используете isNan (), но и предоставили полностью подробный ответ. Это именно то, что я искал, когда я нашел этот вопрос в Google.
mjohnsonengr

1
«.... дал неправильные результаты для вышеупомянутых случаев», я бы не сказал, что неправильно, просто иначе, потому что global isNaNсначала преобразует аргумент в числовое значение.
Феликс Клинг

1
@FelixKling Пожалуйста, проверьте обновленный ответ. Спасибо.
Допедуд

1
isNaN ("lorem ipsum"); // правда с ES5 потрясла меня
Ник Пинеда

2
@NickPineda Ощущение настолько взаимное, но, в конце концов, MDN может объяснить это следующим образом: «Если аргумент функции isNaN имеет тип Number, значение сначала приводится к Number. Затем полученное значение проверяется, чтобы определить, NaN «.
допингдуд

16

NaN - это особая ценность, которую нельзя так проверить. Интересно, что я просто хотел поделиться этим

var nanValue = NaN;
if(nanValue !== nanValue) // Returns true!
    alert('nanValue is NaN');

Это возвращает истину только для значений NaN и является безопасным способом тестирования. Должен определенно быть обернут в функцию или, по крайней мере, прокомментирован, потому что, очевидно, нет смысла проверять, не совпадают ли одна и та же переменная, хе-хе.


1
Это не совсем надежный способ. Согласно спецификации. переменная! == переменная является наиболее надежным способом проверки на NaN
allsyed

1
Смотрите мой ответ выше на этом ^
Jazzy

14

Вы должны использовать isNaN(value)вызов глобальной функции, потому что:

  • Поддерживается кросс-браузер
  • Смотрите isNaN для документации

Примеры:

 isNaN('geoff'); // true
 isNaN('3'); // false

Я надеюсь, что это поможет вам.


1
Да, isNaN('') //falseно parseInt('') //NaN. То же самое можно сказать и для null.
Тихий пингвин

13

Начиная с ES6 , Object.is(..)это новая утилита, которую можно использовать для проверки двух значений на абсолютное равенство:

var a = 3 / 'bar';
Object.is(a, NaN); // true


9

Чтобы исправить проблему с '1.2geoff'анализом, просто используйте Number()вместо этого анализатор.

Итак, а не это:

parseFloat('1.2geoff'); // => 1.2
isNaN(parseFloat('1.2geoff')); // => false
isNaN(parseFloat('.2geoff')); // => false
isNaN(parseFloat('geoff')); // => true

Сделай это:

Number('1.2geoff'); // => NaN
isNaN(Number('1.2geoff')); // => true
isNaN(Number('.2geoff')); // => true
isNaN(Number('geoff')); // => true

РЕДАКТИРОВАТЬ: я только что заметил еще одну проблему из этого, хотя ... ложные значения (и true, как настоящий логический) передаются в Number()качестве 0! В этом случае ... parseFloat работает каждый раз вместо этого. Итак, вернемся к этому:

function definitelyNaN (val) {
    return isNaN(val && val !== true ? Number(val) : parseFloat(val));
}

И это охватывает, казалось бы, все. Я оценил его на 90% медленнее, чем у Лодаша, _.isNaNно тогда он не охватывает все NaN:

http://jsperf.com/own-isnan-vs-underscore-lodash-isnan

Просто чтобы прояснить, моя заботится о человеческой буквальной интерпретации чего-то, что является «Не числом», а Лодаш заботится о компьютерной буквальной интерпретации проверки, является ли что-то «NaN».


7

Хотя ответ @chiborg является верным, следует отметить следующее:

parseFloat('1.2geoff'); // => 1.2
isNaN(parseFloat('1.2geoff')); // => false
isNaN(parseFloat('.2geoff')); // => false
isNaN(parseFloat('geoff')); // => true

Суть в том, что если вы используете этот метод для проверки ввода, результат будет довольно либеральным.

Итак, да, вы можете использовать parseFloat(string)(или в случае полных чисел parseInt(string, radix)), а затем обернуть это с помощью isNaN(), но будьте внимательны с полученными числами, переплетенными с дополнительными нечисловыми символами.


1
Интересно. Любой способ противостоять этому и обнаружить, что «1.2geoff» на самом деле не является допустимой числовой строкой?
Гейб Халсмер

2
Обратите внимание, что это происходит только тогда, когда строка начинается с цифры. parseFloat('test1.2')вернется NaN.
Эдуард Лука

6

Простое решение!

ДЕЙСТВИТЕЛЬНО супер просто! Вот! Есть этот метод!

function isReallyNaN(a) { return a !== a; };

Используйте так же просто, как:

if (!isReallyNaN(value)) { return doingStuff; }

Смотрите тест производительностиhere с помощью этой функции противselected answer

Также: см. Ниже 1-й пример для пары альтернативных реализаций.


Пример:

function isReallyNaN(a) { return a !== a; };

var example = {
    'NaN': NaN,
    'an empty Objet': {},
    'a parse to NaN': parseFloat('$5.32'),
    'a non-empty Objet': { a: 1, b: 2 },
    'an empty Array': [],
    'a semi-passed parse': parseInt('5a5'),
    'a non-empty Array': [ 'a', 'b', 'c' ],
    'Math to NaN': Math.log(-1),
    'an undefined object': undefined
  }

for (x in example) {
    var answer = isReallyNaN(example[x]),
        strAnswer = answer.toString();
    $("table").append($("<tr />", { "class": strAnswer }).append($("<th />", {
        html: x
    }), $("<td />", {
        html: strAnswer
    })))
};
table { border-collapse: collapse; }
th, td { border: 1px solid; padding: 2px 5px; }
.true { color: red; }
.false { color: green; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table></table>

Есть несколько альтернативных путей, которые вы выбираете для реализации, если вы не хотите использовать метод с альтернативным именем и хотели бы обеспечить его глобальную доступность. Предупреждение Эти решения включают изменение собственных объектов и могут быть не самым лучшим решением. Всегда соблюдайте осторожность и помните, что другие библиотеки, которые вы можете использовать, могут зависеть от собственного кода или аналогичных изменений.

Альтернативная реализация 1: Заменить собственный isNaNметод.

//  Extremely simple. Just simply write the method.
window.isNaN = function(a) { return a !==a; }

Альтернативная реализация 2: добавление к объекту нумерации * Предложено, так
как оно также является полизаполнением для ECMA 5-6

Number['isNaN'] || (Number.isNaN = function(a) { return a !== a });
//  Use as simple as
Number.isNaN(NaN)

Проверка альтернативного раствора, если она пуста

Простой метод окна я написал этот тест, если объект пуст . Это немного отличается тем, что не дает, если элемент «точно» NaN , но я решил, что это будет важно, так как это может быть полезно при поиске пустых элементов.

/** isEmpty(varried)
 *  Simple method for testing if item is "empty"
 **/
;(function() {
   function isEmpty(a) { return (!a || 0 >= a) || ("object" == typeof a && /\{\}|\[(null(,)*)*\]/.test(JSON.stringify(a))); };
   window.hasOwnProperty("empty")||(window.empty=isEmpty);
})();

Пример:


Очень глубокая проверка, если пуст

Этот последний идет немного глубже, даже проверяя, заполнен ли объект пустыми объектами. Я уверен, что в нем есть место для улучшений и возможных ям, но пока что, похоже, ловит почти все.


1
@ PaulD. Возможно, это его приложение, но я не вижу принятого ответа. На самом деле, я вижу только около 5 ответов, но я вижу, что есть 15
SpYk3HH

1
Какое приложение вы используете?
Пол Д. Уэйт

2
@ PaulD.Waite SE один для Android. на галактике s3
SpYk3HH

1
Ага. У меня нет приложения, чтобы посмотреть самому, но вот ссылка на принятый ответ: stackoverflow.com/a/2652335/20578
Пол Д. Уэйт

@ PaulD.Waite А, понятно. Я полагаю, что в прямом ответе только на вопрос сам по себе этот ответ может быть достаточным. Я отправил свой ответ на другой вопрос в связи с "JS способ проверить, действительно ли" NaN ", так isNaNкак не является надежным. Там меня прокомментировали и сказали, что этот вопрос лучше подойдет для моего ответа, поэтому перенес его сюда. Просто добавьте что-нибудь полезное / полезное в связи с этой проблемой, которая появится в поиске Google по данной проблеме is it NaN?. С другой стороны, мой ответ будет более точным, чем выбранный ответ.
SpYk3HH

5

Я просто хочу поделиться другой альтернативой, она не обязательно лучше, чем у других здесь, но я думаю, что стоит посмотреть:

function customIsNaN(x) { return (typeof x == 'number' && x != 0 && !x); }

Логика заключается в том, что каждое число, кроме 0и NaNприведено кtrue .

Я сделал быстрый тест, и он работает так же хорошо, как Number.isNaN и проверяет себя на ложность. Все три работают лучше, чемisNan

Результаты

customIsNaN(NaN);            // true
customIsNaN(0/0);            // true
customIsNaN(+new Date('?')); // true

customIsNaN(0);          // false
customIsNaN(false);      // false
customIsNaN(null);       // false
customIsNaN(undefined);  // false
customIsNaN({});         // false
customIsNaN('');         // false

Может стать полезным, если вы хотите избежать нарушения isNaNфункции.


5

Если ваша среда поддерживает ECMAScript 2015 , вы можете использовать Number.isNaNее, чтобы убедиться, что значение действительноNaN .

Проблема в isNaNтом, что , если вы используете это с нечисловыми данными, применяется несколько непонятных правил (согласно MDN). Например,

isNaN(NaN);       // true
isNaN(undefined); // true
isNaN({});        // true

Итак, в средах, поддерживаемых ECMA Script 2015, вы можете использовать

Number.isNaN(parseFloat('geoff'))

7
Моя среда поддерживает только ECMAScript XP Home Edition :(
Пол Д. Уэйт,

1
@ PaulD.Waite (надеюсь, вы имели в виду IE 6: D) Нет проблем :-) Просто помните, что это isNaNможет привести к неприятностям, и не забывайте использовать Number.isNaNв средах ECMAScript 2015 :-)
thefourtheye

5

NaN в JavaScript означает «не число», хотя на самом деле его тип - число.

typeof(NaN) // "number"

Чтобы проверить, имеет ли переменная значение NaN, мы не можем просто использовать функцию isNaN (), потому что isNaN () имеет следующую проблему, см. Ниже:

var myVar = "A";
isNaN(myVar) // true, although "A" is not really of value NaN

Здесь действительно происходит то, что myVar неявно приводится к числу:

var myVar = "A";
isNaN(Number(myVar)) // true. Number(myVar) is NaN here in fact

Это действительно имеет смысл, потому что «А» на самом деле не число. Но мы действительно хотим проверить, действительно ли myVar имеет значение NaN.

Так что isNaN () не может помочь. Тогда что мы должны делать вместо этого?

В свете того, что NaN является единственным значением JavaScript, которое обрабатывается неравномерно для самого себя, мы можем проверить его равенство самому себе, используя! ==

var myVar; // undefined
myVar !== myVar // false

var myVar = "A";
myVar !== myVar // false

var myVar = NaN
myVar !== myVar // true

Таким образом, чтобы заключить , что если это правда, что переменная! == сама, то эта переменная точно имеет значение NaN:

function isOfValueNaN(v) {
    return v !== v;
}

var myVar = "A";
isNaN(myVar); // true
isOfValueNaN(myVar); // false

4

Я использую функцию подчеркивания,isNaN потому что в JavaScript:

isNaN(undefined) 
-> true

По крайней мере, помните об этом.


10
Я смущен. Почему isNaN, возвращающий true, когда передано, undefinedбудет некорректным поведением? Это правда, что undefinedэто не число, не так ли?
Xaxis

3
@Xaxis NaN не следует считать эквивалентным неопределенному, они оба являются особыми значениями с определенными и разными значениями. Подумайте об этом: у меня есть значение, но я не говорю, что это такое, может быть, это число, и, возможно, это не так, с вашей точки зрения, оно не определено.
Корин

1
@Corin undefinedможет быть чем-то иным NaN, но это не число, поэтому isNaN(undefined)должно быть (и есть)true
neuhaus

4

Возможно также это:

function isNaNCustom(value){
    return value.toString() === 'NaN' && 
           typeof value !== 'string' && 
           typeof value === 'number'
}

3

Кажется, что isNaN () не поддерживается в Node.js из коробки.
Я работал с

var value = 1;
if (parseFloat(stringValue)+"" !== "NaN") value = parseFloat(stringValue);

Конечно, но я не спрашивал о Node.js.
Пол Д. Уэйт


2
NaN === NaN;        // false
Number.NaN === NaN; // false
isNaN(NaN);         // true
isNaN(Number.NaN);  // true

Оператор равенства (== и ===) нельзя использовать для проверки значения с NaN.

Посмотрите на документацию Mozilla . Глобальное свойство NaN - это значение, представляющее Not-A-Numbe.

Лучший способ - использовать функцию isNaN (), которая является встроенной функцией для проверки NaN. Все браузеры поддерживают способ ..


2

Правило таково:

NaN != NaN

Проблема функции isNaN () в том, что она может возвращать неожиданный результат в некоторых случаях:

isNaN('Hello')      //true
isNaN('2005/12/12') //true
isNaN(undefined)    //true
isNaN('NaN')        //true
isNaN(NaN)          //true
isNaN(0 / 0)        //true

Лучший способ проверить, действительно ли значение NaN:

function is_nan(value) {
    return value != value
}

is_nan(parseFloat("geoff"))

1

Согласно IEEE 754 все отношения с участием NaN оцениваются как ложные, кроме! =. Таким образом, например, (A> = B) = false и (A <= B) = false, если A или B или оба являются / являются NaN.


1

Я написал этот ответ на другой вопрос о StackOverflow, когда другой проверяет, когда, NaN == nullно затем он был отмечен как дубликат, поэтому я не хочу тратить свою работу.

Посмотрите на Сеть разработчиков Mozilla о NaN.


Короткий ответ

Просто используйте, distance || 0когда вы хотите убедиться, что вы цените правильное число или isNaN()проверить его.

Длинный ответ

NaN (Not-a-Number) - это странный глобальный объект в javascript, часто возвращаемый при сбое какой-либо математической операции.

Вы хотели проверить, NaN == nullкакие результаты false. Hovewer даже NaN == NaNрезультаты с false.

Простой способ узнать, является ли переменная NaNглобальной функцией isNaN().

Другое, x !== xкоторое верно только тогда, когда х является NaN. (спасибо, что напомнили @ Raphael-Schweikert)

Но почему короткий ответ сработал?

Давайте выясним.

Когда вы звоните, NaN == falseрезультат false, то же самое с NaN == true.

Где-то в спецификациях JavaScript есть запись с всегда ложными значениями, которая включает в себя:

  • NaN - не номер
  • "" - пустой строкой
  • false - логическое значение false
  • null - нулевой объект
  • undefined - неопределенные переменные
  • 0 - числовое 0, включая +0 и -0

1
«Единственный простой способ выяснить, является ли переменная NaN глобальной функцией isNaN ()» - неверно; есть еще один простой способ: var xIsNaN = x !== x;это дает истину, только если х есть NaN.
Рафаэль Швейкерт

1

Другое решение упомянуто на странице parseFloat MDN

Он обеспечивает функцию фильтра для строгого анализа

var filterFloat = function (value) {
    if(/^(\-|\+)?([0-9]+(\.[0-9]+)?|Infinity)$/
      .test(value))
      return Number(value);
  return NaN;
}


console.log(filterFloat('421'));               // 421
console.log(filterFloat('-421'));              // -421
console.log(filterFloat('+421'));              // 421
console.log(filterFloat('Infinity'));          // Infinity
console.log(filterFloat('1.61803398875'));     // 1.61803398875
console.log(filterFloat('421e+0'));            // NaN
console.log(filterFloat('421hop'));            // NaN
console.log(filterFloat('hop1.61803398875'));  // NaN

И тогда вы можете использовать, isNaNчтобы проверить, если этоNaN


1

Точный способ проверить это:

//takes care of boolen, undefined and empty

isNaN(x) || typeof(x) ==='boolean' || typeof(x) !=='undefined' || x!=='' ? 'is really a nan' : 'is a number'

1

Я создал эту маленькую функцию, которая работает как шарм. Вместо того, чтобы проверять NaN, который кажется нелогичным, вы проверяете число. Я уверен, что я не первый, кто делает это таким образом, но я думал, что поделюсь.

function isNum(val){
    var absVal = Math.abs(val);
    var retval = false;
    if((absVal-absVal) == 0){
        retval = true
    }

    return retval;
}


1

Ответ Марксизма работает хорошо, но он не возвращает ложь для Infinity поскольку Бесконечность технически не число.

я придумал isNumberфункцию, которая будет проверять, является ли это число.

function isNumber(i) {
    return !isNaN(i && i !== true ? Number(i) : parseFloat(i)) && [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY].indexOf(i) === -1;
}

console.log(isNumber(Infinity));
console.log(isNumber("asdf"));
console.log(isNumber(1.4));
console.log(isNumber(NaN));
console.log(isNumber(Number.MAX_VALUE));
console.log(isNumber("1.68"));

ОБНОВЛЕНИЕ: я заметил, что этот код не работает для некоторых параметров, поэтому я сделал его лучше.

function isNumber(i) {//function for checking if parameter is number
if(!arguments.length) {
throw new SyntaxError("not enough arguments.");
	} else if(arguments.length > 1) {
throw new SyntaxError("too many arguments.");
	} else if([Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY].indexOf(i) !== -1) {
throw new RangeError("number cannot be \xB1infinity.");
	} else if(typeof i === "object" && !(i instanceof RegExp) && !(i instanceof Number) && !(i === null)) {
throw new TypeError("parameter cannot be object/array.");
	} else if(i instanceof RegExp) {
throw new TypeError("parameter cannot be RegExp.");
	} else if(i == null || i === undefined) {
throw new ReferenceError("parameter is null or undefined.");
	} else {
return !isNaN(i && i !== true ? Number(i) : parseFloat(i)) && (i === i);
	}
}
console.log(isNumber(Infinity));
console.log(isNumber(this));
console.log(isNumber(/./ig));
console.log(isNumber(null));


Ваша предпосылка бесконечность технически, а не число технически ошибочно: math.stackexchange.com/questions/36289/is-infinity-a-number . Из того, что я прочитал, я узнал, что бесконечность - это число, зависит от контекста.
Джон П

я собираюсь перенести это на другой вопрос
adddff

1
alert("1234567890.".indexOf(String.fromCharCode(mycharacter))>-1);

Это не элегантно. но после попытки isNAN () я пришел к этому решению, которое является другой альтернативой. В этом примере я также разрешил '.' потому что я маскируюсь для поплавка. Вы также можете отменить это, чтобы убедиться, что номера не используются.

("1234567890".indexOf(String.fromCharCode(mycharacter))==-1)

Это односимвольная оценка, но вы также можете просмотреть строку для проверки любых чисел.


1

Вы можете проверить NaN, используя функцию javascript isNaN. Просто передав число или значение в функцию isNaN

isNaN(123) //false
isNaN(-1.23) //false
isNaN(5-2) //false
isNaN(0) //false
isNaN('123') //false
isNaN('Hello') //true
isNaN('2005/12/12') //true
isNaN('') //false
isNaN(true) //false
isNaN(undefined) //true
isNaN('NaN') //true
isNaN(NaN) //true
isNaN(0 / 0) //true


0

Является ли (NaN> = 0) ? ...... " Я не знаю ".

function IsNotNumber( i ){
    if( i >= 0 ){ return false; }
    if( i <= 0 ){ return false; }
    return true;
}

Условия выполняются только если ИСТИНА .

Не на ЛОЖЬ .

Не на " Я не знаю ".


не очень полезно, если вы явно ищете значения NaN, вместо того, чтобы искать противоположное
liviu blidar
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.