NaN
, или Not a Number, является распространенным источником разочарования для разработчиков JavaScript из-за его, казалось бы, непоследовательной реализации. Так в чем же дело?
Почему существует NaN?
NaN
— это обычно используемый термин в кодировании для представления вывода математического выражения, которое не является числом. Это не 0, это не бесконечность, это просто не существует числа.
Интересно, что если вы запустите typeof NaN
, оно будет равно number
— NaN
— это числовой тип. Это может показаться забавным, учитывая название — как Not a Number
может быть числового типа?
JavaScript (и большинство других языков) обрабатывает NaN
как число, поэтому ваш код не выдает ошибку, когда вы получаете NaN
. В вашем приложении вы не обязательно хотите, чтобы код аварийно завершал работу, если вы окажетесь в ситуации, когда NaN
было возвращено. Например, если вы создали приложение-калькулятор, а пользователь ввел √-1, вы бы не хотели, чтобы это привело к сбою вашего приложения.
Когда возникает NaN?
Есть пять ситуаций, которые приводят к NaN
в JavaScript:
1. Результат математически невозможен, например Math.sqrt(-1)
2. Одно из значений в выражении равно NaN
, например NaN + 2
или Math.sqrt(-1) * 10
4. Операция, отличная от +
, включающая строку, например. 'hello' / 'hi'
5. Значение, которое не может быть преобразовано в число, например Number("hello")
Сравнение NaN (или почему NaN не равно NaN?)
Проверяя, является ли число NaN
, первое, к чему мы можем обратиться, это NaN === NaN
. Однако, что удивительно, это возвращает False. Они могут выглядеть одинаково, но это не так. И это не потому, что они являются ссылками на разные объекты.
Это происходит из-за выражения вроде Math.sqrt(-1) === Infinity / Infinity
. Значение слева определенно не совпадает со значением справа. Они оба могут закончиться как NaN
, но они оба были созданы совершенно по-разному.
Итак, как мы можем проверить, является ли число действительно числом?
❌ NaN == NaN
Это не совсем одно и то же значение по причине, описанной выше.
❌ NaN === NaN
Это также не совсем одно и то же значение по причине, описанной выше.
❌ [NaN].indexOf(NaN)
Это возвращает -1
(не найдено) по той же причине, что описана выше.
✅ естьNaN(NaN)
isNaN()
— это встроенная функция JavaScript, позволяющая проверить, равно ли значение NaN
. Один интересный момент заключается в том, что он попытается привести не числа к числам, и если это не удастся, он оценит NaN
, который затем вернет True. Например, isNaN("string")
возвращает True.
✅ Число.isNaN(NaN)
Number.isNaN()
почти идентична вышеприведенной функции, за исключением того, что она не будет пытаться преобразовать нечисловые значения в числа. Он возвращает true только для первых трех причин, по которым возникает NaN
, то есть когда математически происходит Not a Number.
✅ Object.is(NaN, NaN)
Object.is()
использует равенство одинаковых значений, чтобы определить, являются ли два значения функционально идентичными друг другу.
✅ [NaN]. включает (NaN)
[].includes()
использует расширение равенства одинаковых значений, называемое равенство одинаковых значений и нулей, поэтому в этом случае оно также возвращает true.
NaN
могут сбивать с толку, и для их сравнения существует ряд абстрактных правил. Надеюсь, эта история была полезной и удачи вам в работе с номерами!