parseInt
est pratique. Il est embarqué nativement dans JavaScript et permet de convertir une chaîne de caractère (String
) en entier. JavaScript étant permessif historiquement1, n'importe quelle valeur peut lui être passée. Il va silencieucesment la convertir en String
(à l'aide de la méthode toString
embarquée nativement dans chaque instance d'Object
), puis effectuer le parseInt
.
D'où :
parseInt("0.0000008", 10); // 0, ok tout va bien
parseInt(0.0000008, 10); // 8 WTF ?!
Etapes (grossières) de parseInt(nb)
sous le capot 2 :
var nbTemp = toString(nb);
parseInt(nbTemp);
Le problème vient de toString()
. En effet, cette fonction native transforme 3 les nombres décimaux à plus de six décimales après la virgule en cette notation : Xe-n
(exemple : 8e-7
).
Donc, avec nb = 0.0000008
:
var nbTemp = toString(0.0000008); // "8e-7"
parseInt("8e-7"); // 8
N'utiliser parseInt qu'avec des chaînes. En fait, parseInt
aurait dû être nommé parseStringToInt()
.
Une solution possible, utiliser la spéc. de la prochaine norme ES6 : Number.isNumber
function parseIntSafe(n) {
return typeof n === "number" && isFinite(n) && n >= (Number.MIN_SAFE_INTEGER || -9007199254740991) && n <= (Number.MAX_SAFE_INTEGER || 9007199254740992) && Math.floor(n) === n? n : NaN;
}
// Integers
console.log(parseIntSafe(4597));
console.log(parseIntSafe(8e3));
console.log(parseIntSafe(1e19));
// !Integers
console.log(parseIntSafe("4598"));
console.log(parseIntSafe(Number.MAX_VALUE));
console.log(parseIntSafe(Infinity));
console.log(parseIntSafe(NaN));
console.log(parseIntSafe({}));
console.log(parseIntSafe(false));
console.log(parseIntSafe(true));
console.log(parseIntSafe(null));
console.log(parseIntSafe(undefined));
console.log(parseIntSafe("lol"));
console.log(parseIntSafe("9.489"));
console.log(parseIntSafe("4,579,312"));
console.log(parseIntSafe("5,2"));
console.log(parseIntSafe("8e3"));
console.log(parseIntSafe(".5"));
Ou alors, préférez une méthode de Golfing qui fonctionne quelque soit le type :
"0.0000008" ^ 0 // string (primitive)
~~0.0000008 // number (primitive)
new String('0.0000008') >> 0 // object wrapper string
String('0.0000008') << 0 // string (primitive)
new Number(0.0000008) | 0 // object wrapper number
Avez-vous une autre méthode pour parser des entiers en JavaScript ?