Un nome migliore per NaN
, descriverne il significato in modo più preciso e meno confuso, sarebbe un'eccezione numerica . È in realtà un altro tipo di oggetto di eccezione mascherato da un tipo primitivo (secondo la progettazione del linguaggio), dove allo stesso tempo non viene trattato come primitivo nel suo falso auto-confronto. Da qui la confusione. E fintanto che il linguaggio "non prenderà la sua decisione" per scegliere tra l'oggetto di eccezione appropriato e il numero primitivo , la confusione rimarrà.
La famigerata non-uguaglianza di NaN
se stesso, di entrambi ==
e===
è una manifestazione del disegno confuso che costringe questo oggetto d'eccezione ad essere un tipo primitivo. Ciò infrange il principio fondamentale secondo cui una primitiva è determinata unicamente dal suo valore . Se NaN
si preferisce essere visto come un'eccezione (di cui possono esserci diversi tipi), allora non dovrebbe essere "venduto" come primitivo. E se si vuole essere primitivo, tale principio deve valere. Finché è rotto, come abbiamo in JavaScript, e non possiamo davvero decidere tra i due, rimarrà la confusione che porta a un carico cognitivo non necessario per tutti i soggetti coinvolti. Che, tuttavia, è davvero facile da risolvere semplicemente facendo una scelta tra i due:
- creare
NaN
un oggetto eccezione speciale contenente le informazioni utili su come è nata l'eccezione, invece di buttare via quelle informazioni come ciò che è attualmente implementato, portando a un codice più difficile da debug;
- o crea
NaN
un'entità del tipo primitivonumber
(che potrebbe essere meno confusamente chiamato "numerico"), nel qual caso dovrebbe essere uguale a se stesso e non può contenere altre informazioni; quest'ultima è chiaramente una scelta inferiore.
L'unico vantaggio immaginabile di forzare NaN
nel number
tipo è di essere in grado di riportarlo in qualsiasi espressione numerica. Il che, tuttavia, rende la scelta fragile, perché il risultato di qualsiasi espressione numerica contenente NaN
sarà o NaN
, o porterà a risultati imprevedibili come la NaN < 0
valutazione difalse
, ovvero il ritorno boolean
invece di mantenere l'eccezione.
E anche se "le cose sono come sono", nulla ci impedisce di fare questa chiara distinzione per noi stessi, per aiutare a rendere il nostro codice più prevedibile e facilmente debuggabile. In pratica, ciò significa identificare quelle eccezioni e gestirle come eccezioni. Il che, sfortunatamente, significa più codice, ma si spera venga mitigato da strumenti come TypeScript di Flowtype.
E poi abbiamo la distinzione tra disordine silenzioso e rumoroso, ovvero segnalazioneNaN
. Il che riguarda davvero il modo in cui vengono gestite le eccezioni, non le eccezioni stesse e nulla di diverso dalle altre eccezioni.
Allo stesso modo, Infinity
e +Infinity
sono elementi di tipo numerico che sorgono nell'estensione della linea reale ma non sono numeri reali. Matematicamente, possono essere rappresentati da sequenze di numeri reali che convergono in uno +
o -Infinity
.