
Utilisez Number(chaine) pour convertir une chaîne qui doit être entièrement numérique (« 42 », « 3.99 ») : elle renvoie NaN au moindre caractère parasite. Utilisez parseInt(chaine, 10) ou parseFloat(chaine) pour extraire le nombre au début d’une chaîne comme « 42px ». Vérifiez toujours le résultat avec Number.isNaN() avant de calculer.
Une valeur lue dans un champ de formulaire, un attribut HTML, une URL ou un fichier JSON mal typé arrive toujours sous forme de chaîne de caractères. Avant de calculer, il faut la convertir en nombre. JavaScript offre quatre façons de le faire, et elles ne réagissent pas de la même manière face à « 42px », « 3,99 » ou une chaîne vide. Voici ce que chacune renvoie vraiment, vérifié sous Node.js 22.
Les quatre méthodes en un tableau
| Chaîne | 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 |
"" (vide) | NaN | NaN | 0 | 0 |
"12,5" | 12 | 12 | NaN | NaN |
"1e3" | 1 | 1000 | 1000 | 1000 |
"0x1f" | 0 (base 10 forcée) | 0 | 31 | 31 |
"abc" | NaN | NaN | NaN | NaN |
"Infinity" | NaN | Infinity | Infinity | Infinity |
null | NaN | NaN | 0 | 0 |
undefined | NaN | NaN | NaN | NaN |
Deux familles se dessinent. parseInt et parseFloat extraient : elles lisent la chaîne depuis le début, s’arrêtent au premier caractère qui n’est pas un chiffre et renvoient ce qu’elles ont lu. Number() et l’opérateur + convertissent tout ou rien : la chaîne entière doit représenter un nombre, sinon c’est NaN. Une exception qui pique : la chaîne vide vaut 0 pour elles.
parseInt() : l’entier au début de la chaîne
parseInt('42', 10); // 42
parseInt('42px', 10); // 42 : s'arrête au « p »
parseInt('3.99', 10); // 3 : la partie décimale est ignorée, pas arrondie
parseInt(' 42 ', 10); // 42 : les espaces autour sont tolérés
parseInt('abc', 10); // NaN : aucun chiffre au début
parseInt('', 10); // NaNLe second argument est la base (ou radix). Elle vaut 10 pour un nombre décimal, 16 pour l’hexadécimal, 2 pour le binaire :
parseInt('ff', 16); // 255
parseInt('101', 2); // 5
parseInt('0x1f'); // 31 : sans base, le préfixe 0x fait basculer en hexadécimal
parseInt('08'); // 8 : les moteurs modernes ne lisent plus « 08 » en octalÉcrire la base explicitement, parseInt(s, 10), n’est plus indispensable pour les zéros initiaux depuis ES5, mais c’est toujours la bonne habitude : elle rend l’intention lisible et neutralise le cas 0x.
parseFloat() : le nombre décimal au début de la chaîne
parseFloat('3.99'); // 3.99
parseFloat('12.5px'); // 12.5
parseFloat('.5'); // 0.5
parseFloat('1e3'); // 1000 : la notation scientifique est comprise
parseFloat('3,99'); // 3 : la virgule arrête la lecture
parseFloat('abc'); // NaNparseFloat n’a pas d’argument de base : elle lit toujours en décimal. C’est la fonction à choisir pour extraire une mesure d’une chaîne CSS (« 12.5px », « 1.5rem ») ou d’un texte libre.
Number() : la conversion stricte
Number('42'); // 42
Number('3.99'); // 3.99
Number(' 42 '); // 42 : espaces et retours à la ligne autour sont ignorés
Number('42px'); // NaN : un seul caractère de trop et tout échoue
Number(''); // 0 : attention
Number(' '); // 0 : idem
Number(null); // 0
Number(undefined); // NaN
Number(true); // 1
Number('0x1f'); // 31 : hexadécimal, binaire (0b) et octal (0o) préfixés sont acceptésNumber() est la conversion que vous voulez pour une valeur qui doit être un nombre et rien d’autre : un prix, une quantité, un identifiant. Si l’utilisateur a tapé « 12 euros », vous obtenez NaN et vous pouvez le lui dire, au lieu de calculer avec 12 sans le savoir.
L’opérateur unaire + : Number() en un caractère
+'42'; // 42
+''; // 0
+'abc'; // NaN
'42' * 1; // 42 : la multiplication force aussi la conversion
'42' - 0; // 42
'3' + '4'; // '34' : l'addition, elle, concatène !Le + placé devant une valeur applique exactement Number(). Il est court, très courant dans le code existant, et facile à rater à la relecture : +valeur se confond avec une faute de frappe. Dans un code partagé, Number(valeur) dit la même chose plus clairement. Et n’utilisez jamais l’addition binaire pour convertir : '3' + '4' donne la chaîne '34'.
Gérer NaN correctement
NaN (Not a Number) est le résultat de toute conversion ratée. Il a une propriété piégeuse : il n’est égal à rien, pas même à lui-même.
const n = Number('abc');
n === NaN; // false, toujours
Number.isNaN(n); // true : la bonne façon de tester
isNaN('abc'); // true : mais isNaN convertit d'abord son argument...
Number.isNaN('abc');// false : ... alors que Number.isNaN ne teste que les vrais NaNLe schéma habituel : convertir, tester, appliquer une valeur par défaut ou signaler l’erreur.
function toNumber(valeur, defaut = 0) {
const n = Number(String(valeur).trim());
return Number.isNaN(n) ? defaut : n;
}
toNumber('42'); // 42
toNumber('42px'); // 0 (valeur par défaut)
toNumber('', 10); // 0 : la chaîne vide vaut 0, pas la valeur par défautLa dernière ligne rappelle le piège de la chaîne vide : si un champ vide doit être traité comme « non renseigné », testez-le avant de convertir.
function toNumberStrict(valeur) {
const s = String(valeur).trim();
if (s === '') return NaN;
return Number(s);
}Le cas français : la virgule décimale
Aucune des quatre méthodes ne comprend « 12,5 ». Number renvoie NaN, parseFloat s’arrête à la virgule et renvoie 12, ce qui est pire : le programme continue avec une valeur fausse. Normalisez la saisie avant de convertir.
function parseFr(chaine) {
const normalisee = String(chaine)
.replace(/\s/g, '') // retire les espaces de milliers : « 1 234,56 »
.replace(',', '.'); // virgule décimale -> point
return Number(normalisee);
}
parseFr('12,5'); // 12.5
parseFr('1 234,56'); // 1234.56
parseFr('12.5'); // 12.5 : le point reste acceptéDans un formulaire, <input type="number"> évite le problème : le navigateur affiche la virgule à l’utilisateur français mais transmet toujours un point dans value.
Vérifier qu’une chaîne est bien un nombre
Pour savoir si une chaîne représente un nombre avant de l’utiliser, combinez une conversion stricte et Number.isFinite, qui refuse NaN et 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'); // falseEt pour distinguer un entier d’un décimal une fois converti : Number.isInteger(42) vaut true, Number.isInteger(3.99) vaut false.
Les grands entiers : quand Number ne suffit plus
Number représente exactement les entiers jusqu’à 253 − 1 (9 007 199 254 740 991). Au-delà, la précision se perd sans avertissement : un identifiant de base de données sur 64 bits ou un montant en centimes très élevé peuvent être faussés.
Number('9007199254740993'); // 9007199254740992 : le dernier chiffre a changé
BigInt('9007199254740993'); // 9007199254740993n : exact
Number.MAX_SAFE_INTEGER; // 9007199254740991BigInt ne se mélange pas avec Number dans un calcul et n’accepte pas les décimales, réservez-le aux identifiants et aux entiers vraiment grands.
Quelle méthode choisir ?
- La valeur doit être un nombre et rien d’autre (prix, quantité, identifiant) :
Number(), après avoir écarté la chaîne vide. - Il faut extraire un nombre d’un texte (« 12.5px », « 3 articles ») :
parseFloat()pour un décimal,parseInt(s, 10)pour un entier. - La saisie vient d’un utilisateur français : normaliser la virgule et les espaces, puis
Number(). - Vous relisez du code avec
+valeur: c’estNumber(valeur). Gardez-le si l’équipe en a l’habitude, mais ne convertissez jamais avec l’addition'3' + '4'. - Dans tous les cas : testez avec
Number.isNaN()ouNumber.isFinite()avant de calculer.
L’opération inverse, transformer un nombre en chaîne lisible avec deux décimales ou un séparateur de milliers, est traitée dans Formater un nombre en JavaScript. Pour les bases du langage, le chapitre Variables et types de données du tutoriel explique pourquoi une chaîne et un nombre sont deux types distincts.
Erreurs fréquentes
parseInt("08") vaut 8 dans tous les moteurs modernes, mais parseInt("0x1f") vaut 31 : la chaîne est lue en hexadécimal. Passez toujours la base : parseInt(chaine, 10).Number("12,5") renvoie NaN et parseFloat("12,5") renvoie 12. Remplacez la virgule par un point avant la conversion.NaN === NaN est faux. Utilisez Number.isNaN(valeur), jamais une comparaison directe.Number("") et +"" valent 0, pas NaN. Un champ de formulaire laissé vide devient donc un zéro silencieux : testez chaine.trim() === "" avant de convertir.

