Comment puis-je contourner JavaScript parseInt octal comportement?
Essayez d'exécuter les opérations suivantes dans JavaScript:
parseInt('01'); //equals 1
parseInt('02'); //equals 2
parseInt('03'); //equals 3
parseInt('04'); //equals 4
parseInt('05'); //equals 5
parseInt('06'); //equals 6
parseInt('07'); //equals 7
parseInt('08'); //equals 0 !!
parseInt('09'); //equals 0 !!
J'ai juste appris à la dure que JavaScript pense que le zéro indique une octal entier, et depuis il n'y a pas de "8"
ou "9"
en base 8, la fonction renvoie zéro. Comme lui ou pas, c'est par la conception.
Quelles sont les solutions?
Note: Par souci d'exhaustivité, je suis sur le point de publier une solution, mais c'est une solution que je déteste, donc s'il vous plaît poster d'autres/de meilleures réponses.
Mise à jour:
La 5ème Édition de la norme JavaScript (ECMA-262) introduit une modification importante qui élimine ce problème. Mozilla a une bonne écriture-up.
- Étape 1) Faites-vous une faveur et de toujours mentionner le radix comme mentionné dans les réponses précédentes ainsi que dans Doug livre. Étape 2) Si vous êtes sérieux au sujet de l'apprentissage de JavaScript, puis vous en procurer une copie de Doug livre. Il est inestimable. Mes fav livre jusqu'à présent. Voici une revue pour info: realtech.burningbird.net/learning-javascript/basics/...
- Dans ECMAScript 5ème Édition-compatible navigateurs, comme Internet Explorer 9, la base de paramètre par défaut
10
(décimal), sauf si le nombre à analyser est préfixé avec0x
, par exemple0xFF
, auquel cas la base de paramètre par défaut est 16. Je l'espère, un jour, cette question sera plus qu'un lointain souvenir. - Que diriez-vous simplement
+'08' === 8
? Vrai! Peut-être que vous avez vraiment besoin deparseInt
pour votre code réel, mais pas pour la ci-dessus. - a) ce n'est pas un bug, corrigé le titre b)
Number('08')
- Safari du moteur JavaScript a aligné son comportement plus proche de la spécification ECMAScript. ... la méthode parseInt ne pas analyser les nombres octaux plus voir trac.webkit.org/changeset/103922
- "la 5e Édition...introduit une modification importante qui élimine ce problème" Probablement intéressant de souligner que, même dans la 3e édition (il y a 13 ans), les mises en œuvre ont été "encouragés" par le fait de ne pas le faire: "Quand radix est
0
ouundefined
et la chaîne du numéro commence avec un0
chiffre n'est pas suivie par unx
ouX
, puis la mise en œuvre pourrait, à sa discrétion, d'interpréter le nombre, soit comme étant octal ou décimal. Implémentations sont invités à interpréter des nombres dans ce cas comme étant décimal." (mon emphase) - Merci pour la mise à jour. Je viens de lire dans langue étrange fonctionnalités et je me demandais pourquoi ça ne fonctionne pas.
- Tout comme une note de l'endroit où il se passe à ce moment de temps: Google Docs javascript encore l'analyse à 0.
- Il m'a fallu 3 jours pour détecter cette erreur qui se produit uniquement dans la version ie7 ou le mode de compatibilité dans l'explorateur. Les heures d'ouverture "08:mm" a obtenu des convertis "00:mm".
Vous devez vous connecter pour publier un commentaire.
C'est une commune Javascript gotcha avec une solution simple:
Juste spécifier la base, ou "radix", comme si:
Vous pouvez également utiliser Nombre:
Si vous savoir votre valeur sera dans l'entier signé sur 32 bits à la plage,
~~x
va faire la bonne chose dans tous les scénarios.Si vous regardez binaire pas (
~
), la spécification exige une "ToInt32" la conversion de l'argument qui fait de évident conversion à un Int32 et est spécifiée pour contraindreNaN
les valeurs à zéro.Oui, c'est incroyablement hackish mais c'est tellement pratique...
De la parseInt documentation, utilisez l'option d'radix argument pour spécifier la base-10:
Ce qui me frappe comme pédant, de la confusion, et verbeux (vraiment, un argument supplémentaire dans chaque parseInt?) alors j'espère que il ya une Meilleure Façon.
parseInt
pour une utilisation pratique dans les expressions fonctionnelles, commemap
dans["7","4","09","5"].map(parseInt);
Map
va passer le index de l'élément dans le tableau en tant que second argument, qui sera interprété parparseInt
comme la base, sauf si vous l'envelopper.edit: en faisant votre propre fonction, de faire ce que vous voulez vraiment, c'est juste une option si vous n'aimez pas l'ajout de l' ",10" tout le temps à la parseInt() de l'appel. Il a le désavantage d'être une fonction non standard: plus pratique pour vous si vous l'utilisez beaucoup, mais peut-être plus déroutant pour les autres.
Spécifier la base:
Serait-il très coquine pour remplacer parseInt avec une version qui suppose décimal si elle n'a pas de second paramètre? (remarque: pas testé)
parseInt("0xFFFFFF") === 16777215
, mais avec ce vilain hack en place, il ne fonctionne plusparseInt("0xFFFFFF") === 0
Comment à ce sujet pour les décimales:
et pour faire bonne mesure
MDN Lien
Si vous avez fait un tas de codage déjà avec parseInt et ne voulez pas ajouter ",10" à tout, vous pouvez simplement remplacer la fonction de base 10 de la valeur par défaut:
Qui peuvent confondre un plus tard, lecteur, afin de faire un parseInt10() la fonction pourrait être plus explicite. Personnellement, je préfère utiliser une fonction simple que d'avoir à ajouter ",10" tout le temps - il suffit de crée plus d'opportunités pour les erreurs.