Как проверить, является ли число NaN в JavaScript?
Я пытался выполнить следующие выражения в консоли JavaScript браузера Firefox, и ни одно из них не возвращает true
:
parseFloat('geoff') == NaN;
parseFloat('geoff') == Number.NaN;
Не могу понять, почему так происходит. Как можно правильно проверить, является ли результат NaN
?
5 ответ(ов)
В соответствии с ES6, Object.is(..)
- это новая утилита, которую можно использовать для проверки двух значений на абсолютное равенство:
var a = 3 / 'bar';
Object.is(a, NaN); // true
Стоит отметить, что NaN
равен сам себе по стандарту JavaScript, поэтому для правильного сравнения следует использовать Object.is()
, поскольку обычный оператор равенства (===
) не сработает для NaN
.
NaN (Not a Number) — это особое значение, которое нельзя проверить обычным способом. Интересная деталь, которую я хотел бы поделиться:
var nanValue = NaN;
if (nanValue !== nanValue) // Возвращает true!
alert('nanValue is NaN');
Этот код возвращает true только для значений NaN и является безопасным способом проверки. Однако его стоит завернуть в функцию или, по крайней мере, добавить комментарий, потому что на первый взгляд не имеет смысла проверять, равно ли одно и то же значение самому себе. Хе-хе.
NaN в JavaScript означает "Не число" (Not A Number), хотя его тип на самом деле является number.
typeof(NaN) // "number"
Чтобы проверить, является ли переменная значением NaN, мы не можем просто использовать функцию isNaN(), потому что у функции isNaN() есть кое-какие проблемы, см. ниже:
var myVar = "A";
isNaN(myVar) // true, хотя "A" на самом деле не является значением NaN
На самом деле происходит следующее: myVar неявно приводится к числу:
var myVar = "A";
isNaN(Number(myVar)) // true. Number(myVar) действительно равен NaN здесь
Это имеет смысл, потому что "A" действительно не является числом. Однако что мы действительно хотим проверить, так это если myVar точно равно NaN.
Следовательно, isNaN() не поможет. И что же нам делать вместо этого?
Учитывая, что NaN - это единственное значение в JavaScript, которое считается неравным самому себе, мы можем проверить его равенство самому себе, используя !==:
var myVar; // undefined
myVar !== myVar // false
var myVar = "A";
myVar !== myVar // false
var myVar = NaN;
myVar !== myVar // true
Таким образом, в заключение, если переменная не равна самой себе (v !== v), то это значение точно NaN:
function isOfValueNaN(v) {
return v !== v;
}
var myVar = "A";
isNaN(myVar); // true
isOfValueNaN(myVar); // false
Чтобы исправить проблему, когда '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
из lodash, но последняя не учитывает все NaN:
http://jsperf.com/own-isnan-vs-underscore-lodash-isnan
Для ясности: мой метод учитывает человеческое буквальное восприятие чего-то как "Не число", в то время как lodash заботится о компьютерном буквальном восприятии, проверяя, является ли что-то "NaN".
Правило таково:
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"));
Таким образом, функция is_nan() использует тот факт, что NaN не равно самому себе, чтобы корректно выявить значения NaN без ложных срабатываний, которые могут происходить с isNaN().
Как перенаправить на другую веб-страницу?
Где найти документацию по форматированию даты в JavaScript?
Как определить нажатие клавиши Esc?
Как проверить, содержит ли массив строку в TypeScript?
Ссылка и выполнение внешнего JavaScript-файла, размещенного на GitHub