L'erreur à éviter avec la méthode parseInt en JS

Utilisez-vous vraiment les bonnes méthodes pour récupérer un nombre entier en Javascript ?

Article publié le 07/03/2022, dernière mise à jour le 19/09/2023

Besoin de récupérer la valeur entière d'un nombre en Javascript et vous êtes habitué.e à utiliser la méthode parseInt ?

Je vais vous faire découvrir le vrai danger de cette méthode si elle n'est pas utilisée correctement et les conséquences que cela peut avoir sur le fonctionnement logique de votre application !

Problème

Beaucoup de développeurs et développeuses pensent que la méthode parseInt permet de récupérer la valeur entière d'un nombre, ce qui est vrai, mais seulement en partie.

Le terme "parse" signifie en français "analyse", et n'est pas à négliger car cette méthode n'est pas censé transformer un nombre, mais analyser et extraire un nombre à partir d'une d'une chaine de caractère, puis n'en garder que la partie entière, comme ceci :

parseInt("0.5", 10);
//$> 0 (SUCCESS)

parseInt("0.0000005", 10);
//$> 0 (SUCCESS)

Mais comme Javascript est dynamiquement typé, si on lui passe un paramètre de type "number", il le transformera en chaine de caractère avant de le "parser". Pas optimisé, mais cela fonctionne :

parseInt(0.5, 10);
//$> 0 (SUCCESS)

En réalité, cela ne fonctionne pas toujours, et c'est là qu'arrivent les problèmes :

parseInt(0.0000005, 10);
//$> 5 (FAIL)

Pourquoi la méthode parseInt renvoie le bon résultat avec 0.5 mais pas avec 0.0000005 ? C'est justement à cause de la conversion dynamique "number" -> "string".

Le type "number" en Javascript optimise la gestion de certains nombres en utilisant la notation scientifique.

Le nombre 0.0000005 devient alors 5e-7

La conversion automatique revient alors a appeler la fonction de cette manière :

parseInt("5e-7", 10);
//$> 5

Et comme on demande la partie entière, parseInt va seulement renvoyer la partie entière gauche du chiffre trouvé, soit 5 au lieu de 0.

On retrouve le même problème avec les très grands multiples de 10, exemple :

parseInt(1000000000000000000000, 10);
//$> 1

Solution 1

La première solution que je vous conseille, est de passer systématiquement par du TypeScript.

En effet, la spécification de la méthode parseInt(string, radix) indique bel et bien que le premier paramètre doit strictement être une chaine de caractères, mais comme le Javascript est typé dynamiquement, le code s'exécute quand même.

En passant par du TypeScript, le compilateur (ou le l'extension IDE) vous indiquera que l'appel de cette méthode avec un paramètre de type "number" est illégal, et vous évitera de mauvaises expériences !

Si vous ne connaissez pas (ou peu) le TypeScript, voici un article dans lequel je vous explique ce langage de manière simple.

Solution 2

Comme l'indique la documentation de Mozilla, la méthode parseInt ne doit jamais être utilisée en substitution de la méthode Math.floor, qui elle, prend en paramètre un nombre.

Pour utiliser l'une ou l'autre méthode selon le type du paramètre, vous pouvez utiliser la méthode typeof() pour récupérer le type et utiliser la bonne méthode, comme dans l'exemple ci-dessous :

function toInt(n){
    if(typeof(n) === "number"){
    	return Math.floor(n);
    } else if(typeof(n) === "string") {
    	return parseInt(n, 10);
    } else {
    	throw new Error("...");
    }
}

J'espère que cet article vous aura été utile, et à bientôt sur le blog.


Mick Haupt sur Unsplash

Vous avez terminé l'article ?

Commentaires (0)

pour laisser un commentaire

Aucun commentaire pour l'instant