Quel est le meilleur, number (x) ou parseFloat (x)?

147

Ce qui est mieux?

Je demande cela juste pour raser quelques octets, car je peux utiliser + x au lieu de number (x). Parsefloat fait-il quelque chose de mieux?

Namanyay Goel
la source
2
Les nombres à virgule flottante simple précision occupent 4 octets dans un système 32 bits ainsi que des entiers simples. Je ne sais pas comment javascript gère les flottants, mais je suppose que c'est à peu près la même chose.
Christian du
5
@Christian: Tous les nombres en Javascript sont des flotteurs à double précision.
Guffa
1
J'aurais voté UP pour cette question sans le segment EDIT
LaPuyaLoca

Réponses:

309

La différence entre parseFloat et Number

parseFloat/ parseIntest pour analyser une chaîne, tandis que Number/ +est pour forcer une valeur à un nombre. Ils se comportent différemment. Mais regardons d'abord où ils se comportent de la même manière:

parseFloat('3'); // => 3
Number('3'); // => 3
parseFloat('1.501'); // => 1.501
Number('1.501'); // => 1.501
parseFloat('1e10'); // => 10000000000
Number('1e10'); // => 10000000000

Donc, tant que vous avez une entrée numérique standard, il n'y a pas de différence. Cependant, si votre entrée commence par un nombre et contient ensuite d'autres caractères, parseFloattronque le nombre hors de la chaîne, tandis que Numberdonne NaN(pas un nombre):

parseFloat('1x'); // => 1
Number('1x'); // => NaN

De plus, Numbercomprend l'entrée hexadécimale alors parseFloatque ne:

parseFloat('0x10'); // => 0
Number('0x10'); // => 16

Mais Numberagit bizarrement avec des chaînes vides ou des chaînes contenant uniquement un espace blanc:

parseFloat(''); // => NaN
Number(''); // => 0
parseFloat(' \r\n\t'); // => NaN
Number(' \r\n\t'); // => 0

Dans l'ensemble, je trouve que Numberc'est plus raisonnable, donc j'utilise presque toujours Numberpersonnellement (et vous constaterez que beaucoup de fonctions JavaScript internes l'utilisent Numberégalement). Si quelqu'un tape, '1x'je préfère afficher une erreur plutôt que de la traiter comme s'il avait tapé '1'. Le seul moment où je fais vraiment une exception, c'est lorsque je convertis un style en un nombre, auquel cas parseFloatc'est utile car les styles se présentent sous une forme comme '3px', auquel cas je veux supprimer la 'px'pièce et simplement obtenir le 3, donc je trouve parseFloatutile ici. Mais vraiment, celui que vous choisissez dépend de vous et des formes d'entrée que vous souhaitez accepter.

Notez que l'utilisation de l' +opérateur unaire est exactement la même chose que l'utilisation Numbercomme fonction:

Number('0x10'); // => 16
+'0x10'; // => 16
Number('10x'); // => NaN
+'10x'; // => NaN
Number('40'); // => 40
+'40'; // => 40

Donc, je l'utilise généralement +pour faire court. Tant que vous savez ce qu'il fait, je le trouve facile à lire.

Mur de Nathan
la source
2
Je ne considérerais pas le comportement d' espace blanc => 0Number() comme "bizarre" Je le considérerais même comme plus attendu, l'espace blanc est une valeur vide mais ce n'est pas nul / non défini => 0 est un bon résultat. Gros (+) pour vous pour les vitrines quand même :)
jave.web
4
@NathanWall: Voudrez peut mentionner que Number('Infinity') === InfinityalorsparseInt('Infinity') === NaN
sstur
3
Je n'utiliserais pas +(unaire plus) pour cela, car si vous oubliez un point-virgule sur la ligne précédente, une expression d'addition pourrait être évaluée à la place.
Jackson
1
Pour les cas où ils se comportent de la même manière, j'ai découvert que parseFloat est de 1% à 15% plus lent, devenant plus lent lorsque le nombre de chiffres décimaux dans une chaîne augmente. Avec 1M d'exécution dans mon système, parseFloat ('1.501') est 5% plus lent que Number ('1.501'), et parseFloat ('1.50137585467') est 15% plus lent que Number ('1.50137585467'). Alors, je choisis Number ().
bytepan
1
@ ChrisBrownie55 Wow, bonne prise. Je ne savais pas que parseFloat pouvait faire ça. Je suppose qu'Infinity n'est pas un entier!
sstur
9

La différence est ce qui se produit lorsque l'entrée n'est pas un "nombre correct". Numberretourne NaNtout en parseFloatanalysant "autant que possible". Si elle est appelée, la chaîne vide Numberretourne 0tandis que parseFloat retourne NaN.

Par exemple:

Number("") === 0               // also holds for false
isNaN(parseFloat("")) === true // and null

isNaN(Number("32f")) === true
parseFloat("32f") === 32
Jon
la source
4
Notez que NaN != NaNcependant
Wex
@Wex Oh vous ment qui NaN != NaNévalue VRAI - merci pour le conseil!
jave.web
4
utilisez isNaN () pour tester la valeur NaN, isNaN(NaN)renvoietrue
jave.web
5

Dans ces exemples, vous pouvez voir la différence:

Number('') = 0;
Number(false) = 0;
Number('1a') = NaN;

parseFloat('') = NaN;
parseFloat(false) = NaN;
parseFloat('1a') = 1;

parseFloat est un peu plus lent car il recherche la première apparition d'un nombre dans une chaîne, tandis que le constucteur de nombre crée une nouvelle instance de nombre à partir de chaînes contenant des valeurs numériques avec des espaces ou contenant de fausses valeurs.

PS Si vous êtes intéressé par certaines solutions de conversion de type universelles, vous pouvez lire l'article sur la conversion de type dans mon blog: http://justsimplejs.blogspot.com/2012/08/data-type-conversion.html

micnique
la source
2

Pour une chaîne vide, ils sont différents.

+""et Number("")renvoie 0, tandis que parseFloat("")renvoie NaN.

xdazz
la source
2
J'irais jusqu'à dire que cela parseFloat()a le bon résultat car une chaîne vide n'est PAS le nombre 0(lire: NaN) alors qu'une chaîne avec le caractère "0"est 0;
Christopher
+xrenvoie 0non seulement pour une chaîne vide mais également pour toute chaîne contenant uniquement des espaces. Exemples: +" ", +"\t\t\t", +"\n\n"- tous donnent 0comme résultat
Lukasz Wiktor
2

Autant que je sache, et cela n'a été entendu que par des collègues et pourrait donc être entièrement mal informé, que parseFloat est légèrement plus rapide.

Bien que lors de recherches plus approfondies, il semblerait que cette différence de performances dépende du navigateur.

http://jsperf.com/parseint-vs-parsefloat/6

Jetez un œil à ces résultats jsPerf et passez un appel. (il comprend également + x tests)

Comme indiqué dans la réponse de @xdazz, +""et Number("")return 0while parseFloat("")renvoie NaNdonc Encore une fois, j'irais avec parseFloat, car une chaîne vide ne signifie PAS le nombre 0, seule une chaîne avec le caractère "0"signifie 0;

Christophe
la source
Voici un test plus exhaustif pour trouver un moyen plus rapide de convertir ... parseFloat()est toujours le gagnant.
mindplay.dk