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

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

parseFloat('geoff') == NaN;

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

29 ответов


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

isNaN(parseFloat("geoff"))

для проверки, является ли любой значение NaN, а не просто числа, см. здесь:как вы тестируете NaN в Javascript?


Я только что наткнулся на эту технику в книге Эффективный 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


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

isNaN('geoff');

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

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

насколько значение типа должен быть проверен, является ли это 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 для номера.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;
}

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


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

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

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


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

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

примеры:

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

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


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

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

чтобы исправить проблему, где '1.2geoff' анализируется, просто используйте парсер.

Итак, вместо этого:

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

EDIT:я только что заметил еще одну проблему из этого... ложные значения (и true как реальное логическое значение), переданные в Number() вернуться в 0! В этом случае... вместо этого parseFloat работает каждый раз. Так что вернемся к этому:

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

и это охватывает, казалось бы, все. Я протестированные на 90% медленнее, чем лодашь по _.isNaN но тогда это не покрывает всех НАН:

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

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


в то время как ответ @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(), но имейте в виду gotcha с числами, переплетенными с дополнительными нечисловыми символами.


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

действительно супер просто! Сюда! Этот способ!

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

использовать так же просто, как:

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

посмотреть тест производительности здесь используя этот func vs выбранный ответ

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


пример:

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

var example = {
    'NaN': NaN,
    'an empty Objet': {},
    'a parse to NaN': parseFloat('.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>

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

Альтернативная Реализация 1: Заменить Native isNaN метод.

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

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

Number['isNaN'] || (Number.isNaN = function(a) { return a !== a });
//  Use as simple as
Number.isNaN(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);
})();

пример:

;(function() {
   function isEmpty(a) { return !a || void 0 === a || a !== a || 0 >= a || "object" == typeof a && /\{\}|\[(null(,)*)*\]/.test(JSON.stringify(a)); };
   window.hasOwnProperty("empty")||(window.empty=isEmpty);
})();

var example = {
    'NaN': NaN,
    'an empty Objet': {},
    'a parse to NaN': parseFloat('.32'),
    'a non-empty Objet': { a: 1, b: 2 },
    'an empty Array': new Array(),
    'an empty Array w/ 9 len': new Array(9),
    '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 = empty(example[x]),
		strAnswer = answer.toString();
	$("#t1").append(
		$("<tr />", { "class": strAnswer }).append(
			$("<th />", { html: x }),
			$("<td />", { html: strAnswer.toUpperCase() })
		)
	)
};


function isReallyNaN(a) { return a !== a; };
for(x in example){var answer=isReallyNaN(example[x]),strAnswer=answer.toString();$("#t2").append($("<tr />",{"class":strAnswer}).append($("<th />",{html:x}),$("<td />",{html:strAnswer.toUpperCase()})))};
table { border-collapse: collapse; float: left; }
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 id="t1"><thead><tr><th colspan="2">isEmpty()</th></tr></thead><thead><tr><th>Value Type</th><th>Bool Return</th></tr></thead></table>
<table id="t2"><thead><tr><th colspan="2">isReallyNaN()</th></tr></thead><thead><tr><th>Value Type</th><th>Bool Return</th></tr></thead></table>

Чрезвычайно Глубокая Проверка, Если Пуст

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

function isEmpty(a) {
	if (!a || 0 >= a) return !0;
	if ("object" == typeof a) {
		var b = JSON.stringify(a).replace(/"[^"]*":(0|"0*"|false|null|\{\}|\[(null(,)?)*\]),?/g, '').replace(/"[^"]*":\{\},?/g, '');
		if ( /^$|\{\}|\[\]/.test(b) ) return !0;
		else if (a instanceof Array)  {
			b = b.replace(/(0|"0*"|false|null|\{\}|\[(null(,)?)*\]),?/g, '');
			if ( /^$|\{\}|\[\]/.test(b) ) return !0;
		}
	}
	return false;
}
window.hasOwnProperty("empty")||(window.empty=isEmpty);

var example = {
    'NaN': NaN,
    'an empty Objet': {},
    'a parse to NaN': parseFloat('.32'),
    'a non-empty Objet': { a: 1, b: 2 },
    'an empty Array': new Array(),
    'an empty Array w/ 9 len': new Array(9),
    'a semi-passed parse': parseInt('5a5'),
    'a non-empty Array': [ 'a', 'b', 'c' ],
    'Math to NaN': Math.log(-1),
    'an undefined object': undefined,
    'Object Full of Empty Items': { 1: '', 2: [], 3: {}, 4: false, 5:new Array(3), 6: NaN, 7: null, 8: void 0, 9: 0, 10: '0', 11: { 6: NaN, 7: null, 8: void 0 } },
    'Array Full of Empty Items': ["",[],{},false,[null,null,null],null,null,null,0,"0",{"6":null,"7":null}]
  }

for (x in example) {
	var answer = empty(example[x]),
		strAnswer = answer.toString();
	$("#t1").append(
		$("<tr />", { "class": strAnswer }).append(
			$("<th />", { html: x }),
			$("<td />", { html: strAnswer.toUpperCase() })
		)
	)
};


function isReallyNaN(a) { return a !== a; };
for(x in example){var answer=isReallyNaN(example[x]),strAnswer=answer.toString();$("#t2").append($("<tr />",{"class":strAnswer}).append($("<th />",{html:x}),$("<td />",{html:strAnswer.toUpperCase()})))};
table { border-collapse: collapse; float: left; }
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 id="t1"><thead><tr><th colspan="2">isEmpty()</th></tr></thead><thead><tr><th>Value Type</th><th>Bool Return</th></tr></thead></table>
<table id="t2"><thead><tr><th colspan="2">isReallyNaN()</th></tr></thead><thead><tr><th>Value Type</th><th>Bool Return</th></tr></thead></table>

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

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

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

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

Number.isNaN(parseFloat('geoff'))


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

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

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

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

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

может быть полезным, если вы хотите чтобы избежать сломанной


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

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

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

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


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

//takes care of boolen, undefined and empty

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

function isNotANumber(n) {
  if (typeof n !== 'number') {
    return true;
  } 
  return n !== n;
}

может быть и такое:

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

согласно IEEE 754, все отношения, связанные с NaN, оцениваются как ложные, за исключением !=. Так, например, (А >= Б) = false и (А


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

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


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

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

долго ответ

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

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

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

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

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

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

когда вы называете NaN == false результат false С NaN == true.

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

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

другое решение, описанное в МДН-х

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

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


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

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

    return retval;
}

нашел другой способ, просто для удовольствия.

function IsActuallyNaN(obj) {
  return [obj].includes(NaN);  
}

ответ marksyzm работает хорошо, но он не возвращает false для 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));

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

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

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

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


Is (NaN >= 0) ?...... "Я не знаю".

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

условия выполняются, только если TRUE.

не на FALSE.

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


Итак, я вижу несколько ответов на это,

но я просто использовать:

function isNaN(x){
     return x == x && typeof x == 'number';
}

просто преобразуйте результат в строку и сравните с "NaN".

var val = Number("test");
if(String(val) === 'NaN') {
   console.log("true");
}