Лучшее название NaN
, описывающее его значение более точно и менее запутанно, будет числовым исключением . Это действительно другой тип объекта исключения, замаскированный как имеющий примитивный тип (в соответствии с языковым дизайном), где в то же время он не рассматривается как примитивный в своем ложном самосравнении. Откуда путаница. И до тех пор, пока язык «не решится» выбирать между правильным объектом исключения и примитивной цифрой , путаница останется.
Печально известное неравенство между NaN
собой и тем ==
и другим ===
является проявлением запутанного замысла, заставляющего этот объект исключения становиться примитивным типом. Это нарушает фундаментальный принцип, согласно которому примитив однозначно определяется его ценностью . Если NaN
предпочтительнее рассматривать его как исключение (из которых могут быть разные виды), то его не следует «продавать» как примитив. И если он хочет быть примитивным, этот принцип должен соблюдаться. Пока он сломан, как у нас в JavaScript, и мы не можем на самом деле выбрать между ними, путаница, приводящая к ненужной когнитивной нагрузке для всех участников, останется. Что, однако, действительно легко исправить, просто сделав выбор между двумя:
- либо создать
NaN
специальный объект исключения, содержащий полезную информацию о том, как возникло исключение, а не выбрасывать эту информацию как то, что в настоящее время реализовано, что приводит к сложному для отладки коду;
- или сделать
NaN
объект примитивного типа number
(который можно было бы назвать менее численным) «в числовом виде», в этом случае он должен быть равен самому себе и не может содержать никакой другой информации; последнее явно является худшим выбором.
Единственное мыслимое преимущество принудительного ввода NaN
в number
тип - это возможность вернуть его в любое числовое выражение. Что, однако, делает его хрупким выбором, потому что результат любого содержащего числовое выражение NaN
будет либо иметь NaN
, либо приводить к непредсказуемым результатам, таким как NaN < 0
оценка false
, т.е. возврат boolean
вместо сохранения исключения.
И даже если «все так, как есть», ничто не мешает нам сделать это четкое различие для себя, чтобы сделать наш код более предсказуемым и легче отлаживаемым. На практике это означает выявление этих исключений и рассмотрение их как исключений. Что, к сожалению, означает больше кода, но, надеюсь, будет смягчено такими инструментами, как TypeScript of Flowtype.
И затем у нас есть грязное тихое против шумного ака сигнального NaN
различия . Что на самом деле касается того, как обрабатываются исключения, а не самих исключений, и ничем не отличается от других исключений.
Аналогично, Infinity
и +Infinity
являются элементами числового типа, возникающими в расширении реальной строки, но они не являются действительными числами. Математически они могут быть представлены последовательностями действительных чисел, сходящихся к одному +
или -Infinity
.