Newsletter

parseInt o Number: convertire una stringa in numero in JavaScript

Quattro modi per convertire una stringa in numero in JavaScript, le loro differenze su «42px», «3,99» o una stringa vuota, la gestione di NaN e il metodo da scegliere caso per caso.

Convertire una stringa in numero in JavaScript: parseInt e Number
Risposta rapida

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

javascript
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);        // NaN

Il secondo argomento è la base (o radix). Vale 10 per un numero decimale, 16 per l’esadecimale, 2 per il binario:

javascript
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 ottale

Scrivere 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

javascript
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');      // NaN

parseFloat 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

javascript
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 accettati

Number() è 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

javascript
+'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.

javascript
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 NaN

Lo schema abituale: convertire, testare, applicare un valore predefinito o segnalare l’errore.

toNumber.js
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 predefinito

L’ultima riga ricorda la trappola della stringa vuota: se un campo vuoto deve essere trattato come «non compilato», verificalo prima di convertire.

javascript
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.

parseFr.js
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 accettato

In 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.

javascript
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'); // false

E 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.

javascript
Number('9007199254740993');   // 9007199254740992 : l'ultima cifra è cambiata
BigInt('9007199254740993');   // 9007199254740993n : esatto
Number.MAX_SAFE_INTEGER;      // 9007199254740991

BigInt 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() o Number.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

Dimenticare la base di parseInt 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).
Contare sulla virgola decimale francese Number("12,5") restituisce NaN e parseFloat("12,5") restituisce 12. Sostituisci la virgola con un punto prima della conversione.
Testare NaN con === NaN === NaN è falso. Usa Number.isNaN(valeur), mai un confronto diretto.
Confondere la stringa vuota con lo zero Number("") e +"" valgono 0, non NaN. Un campo di form lasciato vuoto diventa quindi uno zero silenzioso: verifica chaine.trim() === "" prima di convertire.

JavaScript

Damien Flandrin Sviluppatore web dal 2010, creatore di Gekkode e di Email Impact. Ogni articolo è testato su un progetto reale prima della pubblicazione. Contatti
Newsletter

I nuovi test, tutorial e progetti, via e-mail.

Test riproducibili, codice versionato, risultati datati. Mai spam.