I numeri sono un tipo primitivo in JavaScript, ma il solo uso di typeof non differenzia i numeri da NaN o Infinity.
È utile sapere come controllare se un valore è di tipo primitivo numero, dato che JavaScript è un linguaggio dinamicamente tipizzato.
Il modo più semplice per controllare un numero è usare typeof
, che restituirà la stringa "number"
per qualsiasi valore di tipo primitivo numero, incluso NaN
Infinity
, e -Infinity
.
Un esempio in cui un numero potrebbe apparire come un altro tipo, indicando un bug nel mio codice, sarebbe nel parsing della valuta:
In questo caso, saprei che ho dimenticato di analizzare la stringa in un numero quando ottengo il valore di “string
” da typeof
.
Se uso parseFloat()
per controllare il valore della valuta, ma ho dimenticato di togliere il simbolo della valuta, ottengo un parse fallito e un risultato strano:
Oh, no. In questo caso, sembra che typeof
non funzioni come mi aspettavo – perché i valori NaN
sono considerati numeri in JavaScript.
Quando la parola chiave typeof restituisce “number”
Una soluzione ovvia per controllare il tipo primitivo number è usare la typeof
parola chiave, come ho mostrato sopra.
Ma typeof
è una soluzione incompleta, a causa di due valori speciali in JavaScript: NaN
(“Not a Number”) e Infinity
.
Per il mio esempio di valuta, so di avere un bug se il mio valore monetario è NaN
o Infinity
, ma typeof
restituisce "number"
per entrambi questi valori.
Forse il mio input è stato scritto usando un simbolo di valuta, e ho semplicemente cercato di usare parseFloat()
per catturare il valore. Questo risulterebbe in NaN
:
Una funzione isNumber() personalizzata
Arobust, funzione personalizzata isNumber()
userebbe typeof
per controllare il tipo primitivo, controllare i valori NaN
e controllare Infinity
:
Oppure, nel caso in cui si è sicuri che NaN
e Infinity
non verranno fuori, sarebbe sufficiente controllare che typeof==="number"
.
La one-liner
Adoro i one-liner. Penso che debbano essere documentati con dei commenti, ma penso che siano davvero utili, non solo fantasiosi.
Ecco il one-liner per come controllare un numero in JavaScript:
Ma c’è un modo migliore per controllare un numero finito in JavaScript – la funzione helper Number.isFinite()
ha lo stesso comportamento della funzione personalizzata isNumber()
che ho scritto. Includo un esempio nella prossima sezione.
Il modo più semplice per controllare un numero: Number.isFinite()
In realtà non è necessario scrivere funzioni personalizzate per controllare un numero, anche se è un modo istruttivo per ricordare che i valori JavaScript Infinity
-Infinity
, e NaN
sono tutti del tipo primitivo numero.
“Il metodo
Number.isFinite()
determina se il valore passato è un numero finito.” – MDN Docs
Il metodo Number.isFinite()
restituirà true
per i numeri finiti, e false
per Infinity
-Infinity
, e NaN
– esattamente quello che vogliamo:
C’è anche la funzione globale isFinite()
, che eseguirà la coercizione di tipo (come la coercizione di stringhe in numeri), come mostrato sopra.
Discuto questi metodi in profondità nel mio articolo su Infinity
in The Startup:
Controlla se una variabile è un intero
Per controllare se la variabile A è un intero potrei usare l’operatore di uguaglianza libera ==
per vedere se il valore analizzato è uguale a se stesso.
Il seguente frammento di codice fornisce un esempio di come controllare un intero:
Utilizzando typeof
si differenzierebbe una stringa che viene forzata in un numero da un numero reale, come farebbe l’operatore di uguaglianza rigorosa ===
.
Strip out simboli di valuta
Per una migliore, funzione più robusta, potrei voler eliminare prima i simboli di valuta (come il segno del dollaro e tutte le virgole).
L’analisi completa del denaro usando le espressioni regolari in JavaScript va oltre lo scopo di questo articolo, ma questo codice rimuove $
e ,
prima dell’analisi:
Nota che le funzioni globali parseInt()
e parseFloat()
forzano i valori in stringhe, se necessario, e restituiranno NaN
se la coercizione fallisce.
Ci sono anche le funzioni Numbers.parseInt()
e Number.parseFloat()
, che hanno lo stesso esatto comportamento.
Secondo i MDN Docs, queste funzioni duplicate sono state aggiunte a ECMAScript 2015 per la “modularizzazione degli scopi dei globali.”
JavaScript ha effettivamente degli interi separati?
No, JavaScript ha solo un tipo di numero, che è rappresentato internamente come una rappresentazione in virgola mobile a 64 bit.
Quella virgola mobile è il tipo primitivo di dati numero, e c’è anche un tipo chiamato BigInt che può essere usato per numeri arbitrariamente grandi.
Le funzioni globali parseInt()
e parseFloat()
differiscono in ciò che si aspettano e che produrranno, ma non perché ci siano effettivamente tipi interi e in virgola mobile separati in JavaScript.
Conclusione
Controllare un numero in JavaScript non è particolarmente complicato – typeof
funziona sostanzialmente come dovrebbe, finché si è consapevoli che sia NaN
che Infinity
hanno il numero typeof
.
Il modo più semplice per controllare un numero finito (cioè non NaN
o Infinity
) in JavaScript è usare Number.isFinite()
, che non coerciziona i valori ai numeri, o il globale isFinite()
, che esegue la coercizione di tipo.
Controllare la presenza di un intero in particolare comporta l’utilizzo della funzione parseInt()
, seguita dal confronto del valore analizzato con se stesso utilizzando ==
(che coerciziona i valori non numerici, come le stringhe ai numeri) o ===
(che restituisce true solo se entrambi i valori sono numeri).
Sotto il cappuccio, interi e float sono tutti uguali: JavaScript ha solo un tipo di numero, il tipo primitivo number.
Altra lettura
- La funzione
Number.isInteger()
non costringe le stringhe a numeri:
- Sumit Kumar Pradhan ha scritto sul controllo dei numeri su Dev.to:
- Chris Ferdinandi ha discusso l’analisi dei numeri sul suo blog vanilla JS:
- L’espressione regolare
^+(\.{1,2})?$
corrisponde al denaro:
- Sarah Dayan ha scritto sull’analisi del denaro in JavaScript su frontstuff: