
Usa Number(chaine) per convertire una stringa che deve essere interamente numerica («42», «3.99»): restituisce NaN al minimo carattere estraneo. Usa parseInt(chaine, 10) o parseFloat(chaine) per estrarre il numero all'inizio di una stringa come «42px». Controlla sempre il risultato con Number.isNaN() prima di calcolare.
Un valore letto da un campo di form, da un attributo HTML, da un URL o da un file JSON tipizzato male arriva sempre sotto forma di stringa. Prima di calcolare devi convertirlo in numero. JavaScript offre quattro modi per farlo, e non reagiscono allo stesso modo davanti a «42px», «3,99» o a una stringa vuota. Ecco che cosa restituisce davvero ciascuno, verificato con Node.js 22.
I quattro metodi in una tabella
| Stringa | parseInt(s, 10) | parseFloat(s) | Number(s) | +s |
|---|---|---|---|---|
"42" | 42 | 42 | 42 | 42 |
"3.99" | 3 | 3.99 | 3.99 | 3.99 |
"42px" | 42 | 42 | NaN | NaN |
" 42 " | 42 | 42 | 42 | 42 |
"" (vuota) | NaN | NaN | 0 | 0 |
"12,5" | 12 | 12 | NaN | NaN |
"1e3" | 1 | 1000 | 1000 | 1000 |
"0x1f" | 0 (base 10 forzata) | 0 | 31 | 31 |
"abc" | NaN | NaN | NaN | NaN |
"Infinity" | NaN | Infinity | Infinity | Infinity |
null | NaN | NaN | 0 | 0 |
undefined | NaN | NaN | NaN | NaN |
Si disegnano due famiglie. parseInt e parseFloat estraggono: leggono la stringa dall’inizio, si fermano al primo carattere che non è una cifra e restituiscono quello che hanno letto. Number() e l’operatore + convertono tutto o niente: l’intera stringa deve rappresentare un numero, altrimenti è NaN. Un’eccezione che brucia: per loro la stringa vuota vale 0.
parseInt(): l’intero all’inizio della stringa
parseInt('42', 10); // 42
parseInt('42px', 10); // 42 : si ferma alla «p»
parseInt('3.99', 10); // 3 : la parte decimale viene ignorata, non arrotondata
parseInt(' 42 ', 10); // 42 : gli spazi intorno sono tollerati
parseInt('abc', 10); // NaN : nessuna cifra all'inizio
parseInt('', 10); // NaNIl secondo argomento è la base (o radix). Vale 10 per un numero decimale, 16 per l’esadecimale, 2 per il binario:
parseInt('ff', 16); // 255
parseInt('101', 2); // 5
parseInt('0x1f'); // 31 : senza base, il prefisso 0x fa passare all'esadecimale
parseInt('08'); // 8 : i motori moderni non leggono più «08» in ottaleScrivere la base in modo esplicito, parseInt(s, 10), non è più indispensabile per gli zeri iniziali da ES5 in poi, ma resta la buona abitudine: rende leggibile l’intenzione e neutralizza il caso 0x.
parseFloat(): il numero decimale all’inizio della stringa
parseFloat('3.99'); // 3.99
parseFloat('12.5px'); // 12.5
parseFloat('.5'); // 0.5
parseFloat('1e3'); // 1000 : la notazione scientifica viene capita
parseFloat('3,99'); // 3 : la virgola ferma la lettura
parseFloat('abc'); // NaNparseFloat non ha un argomento di base: legge sempre in decimale. È la funzione da scegliere per estrarre una misura da una stringa CSS («12.5px», «1.5rem») o da un testo libero.
Number(): la conversione stretta
Number('42'); // 42
Number('3.99'); // 3.99
Number(' 42 '); // 42 : spazi e ritorni a capo intorno vengono ignorati
Number('42px'); // NaN : basta un carattere di troppo e fallisce tutto
Number(''); // 0 : attenzione
Number(' '); // 0 : idem
Number(null); // 0
Number(undefined); // NaN
Number(true); // 1
Number('0x1f'); // 31 : esadecimale, binario (0b) e ottale (0o) con prefisso sono accettatiNumber() è la conversione che vuoi per un valore che deve essere un numero e nient’altro: un prezzo, una quantità, un identificatore. Se l’utente ha scritto «12 euro», ottieni NaN e puoi dirglielo, invece di calcolare con 12 senza saperlo.
L’operatore unario +: Number() in un carattere
+'42'; // 42
+''; // 0
+'abc'; // NaN
'42' * 1; // 42 : anche la moltiplicazione forza la conversione
'42' - 0; // 42
'3' + '4'; // '34' : l'addizione, invece, concatena!Il + messo davanti a un valore applica esattamente Number(). È corto, molto diffuso nel codice esistente e facile da non vedere in rilettura: +valeur si confonde con un errore di battitura. In un codice condiviso, Number(valeur) dice la stessa cosa in modo più chiaro. E non convertire mai con l’addizione binaria: '3' + '4' dà la stringa '34'.
Gestire NaN correttamente
NaN (Not a Number) è il risultato di ogni conversione fallita. Ha una proprietà insidiosa: non è uguale a niente, nemmeno a sé stesso.
const n = Number('abc');
n === NaN; // false, sempre
Number.isNaN(n); // true : il modo giusto di testare
isNaN('abc'); // true : ma isNaN converte prima il suo argomento...
Number.isNaN('abc');// false : ... mentre Number.isNaN testa solo i veri NaNLo schema abituale: convertire, testare, applicare un valore predefinito o segnalare l’errore.
function toNumber(valeur, defaut = 0) {
const n = Number(String(valeur).trim());
return Number.isNaN(n) ? defaut : n;
}
toNumber('42'); // 42
toNumber('42px'); // 0 (valore predefinito)
toNumber('', 10); // 0 : la stringa vuota vale 0, non il valore predefinitoL’ultima riga ricorda la trappola della stringa vuota: se un campo vuoto deve essere trattato come «non compilato», verificalo prima di convertire.
function toNumberStrict(valeur) {
const s = String(valeur).trim();
if (s === '') return NaN;
return Number(s);
}Il caso francese: la virgola decimale
Nessuno dei quattro metodi capisce «12,5». Number restituisce NaN, parseFloat si ferma alla virgola e restituisce 12, che è peggio: il programma prosegue con un valore sbagliato. Normalizza l’input prima di convertire.
function parseFr(chaine) {
const normalisee = String(chaine)
.replace(/\s/g, '') // toglie gli spazi delle migliaia: «1 234,56»
.replace(',', '.'); // virgola decimale -> punto
return Number(normalisee);
}
parseFr('12,5'); // 12.5
parseFr('1 234,56'); // 1234.56
parseFr('12.5'); // 12.5 : il punto resta accettatoIn un form, <input type="number"> evita il problema: il browser mostra la virgola all’utente francese ma trasmette sempre un punto in value.
Verificare che una stringa sia davvero un numero
Per sapere se una stringa rappresenta un numero prima di usarla, combina una conversione stretta e Number.isFinite, che rifiuta NaN e Infinity.
function estNumerique(chaine) {
const s = String(chaine).trim();
return s !== '' && Number.isFinite(Number(s));
}
estNumerique('42'); // true
estNumerique('3.99'); // true
estNumerique('42px'); // false
estNumerique(''); // false
estNumerique('Infinity'); // falseE per distinguere un intero da un decimale una volta convertito: Number.isInteger(42) vale true, Number.isInteger(3.99) vale false.
Gli interi grandi: quando Number non basta più
Number rappresenta esattamente gli interi fino a 253 − 1 (9.007.199.254.740.991). Oltre, la precisione si perde senza alcun avviso: un identificatore di database a 64 bit o un importo in centesimi molto alto possono risultare falsati.
Number('9007199254740993'); // 9007199254740992 : l'ultima cifra è cambiata
BigInt('9007199254740993'); // 9007199254740993n : esatto
Number.MAX_SAFE_INTEGER; // 9007199254740991BigInt non si mescola con Number in un calcolo e non accetta i decimali; riservalo agli identificatori e agli interi davvero grandi.
Quale metodo scegliere?
- Il valore deve essere un numero e nient’altro (prezzo, quantità, identificatore):
Number(), dopo aver escluso la stringa vuota. - Devi estrarre un numero da un testo («12.5px», «3 articoli»):
parseFloat()per un decimale,parseInt(s, 10)per un intero. - L’input arriva da un utente francese: normalizza la virgola e gli spazi, poi
Number(). - Stai rileggendo del codice con
+valeur: èNumber(valeur). Tienilo se la squadra ci è abituata, ma non convertire mai con l’addizione'3' + '4'. - In ogni caso: verifica con
Number.isNaN()oNumber.isFinite()prima di calcolare.
L’operazione inversa, trasformare un numero in una stringa leggibile con due decimali o un separatore delle migliaia, è trattata in Formattare un numero in JavaScript. Per le basi del linguaggio, il capitolo Variabili e tipi di dati del tutorial spiega perché una stringa e un numero sono due tipi distinti.
Errori frequenti
parseInt("08") vale 8 in tutti i motori moderni, ma parseInt("0x1f") vale 31: la stringa viene letta in esadecimale. Passa sempre la base: parseInt(chaine, 10).Number("12,5") restituisce NaN e parseFloat("12,5") restituisce 12. Sostituisci la virgola con un punto prima della conversione.NaN === NaN è falso. Usa Number.isNaN(valeur), mai un confronto diretto.Number("") e +"" valgono 0, non NaN. Un campo di form lasciato vuoto diventa quindi uno zero silenzioso: verifica chaine.trim() === "" prima di convertire.

