Co jest lepsze, number (x) czy parseFloat (x)?


146

Co jest lepsze?

Pytam o to tylko po to, żeby zgolić kilka bajtów, ponieważ zamiast liczby (x) mogę użyć + x. Czy parsefloat robi coś lepszego?


2
Liczby zmiennoprzecinkowe o pojedynczej precyzji zajmują 4 bajty w systemie 32-bitowym, podobnie jak zwykłe liczby całkowite. Nie wiem, jak javascript obsługuje pływaki, ale myślę, że to prawie to samo.
Christian

5
@Christian: Wszystkie liczby w Javascript to liczby zmiennoprzecinkowe podwójnej precyzji.
Guffa

1
Głosowałbym ZA to pytanie, gdyby nie segment EDIT
LaPuyaLoca

Odpowiedzi:


309

Różnica między parseFloat i Number

parseFloat/ parseIntsłuży do analizowania łańcucha, podczas gdy Number/ +służy do przekształcania wartości na liczbę. Zachowują się inaczej. Ale najpierw spójrzmy, gdzie zachowują się tak samo:

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

Tak długo, jak masz standardowe wejście numeryczne, nie ma różnicy. Jeśli jednak dane wejściowe zaczynają się od liczby, a następnie zawierają inne znaki, parseFloatobcina liczbę z ciągu, a Numberdaje NaN(nie liczbę):

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

Ponadto Numberrozumie szesnastkowe dane wejściowe, a parseFloatnie:

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

Ale Numberdziała dziwnie w przypadku pustych ciągów lub ciągów zawierających tylko białe spacje:

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

Ogólnie uważam, że Numberjest to bardziej rozsądne, więc prawie zawsze używam go Numberosobiście (a przekonasz się, że korzysta również wiele wewnętrznych funkcji JavaScript Number). Jeśli ktoś pisze '1x', wolę pokazać błąd, zamiast traktować go tak, jakby to on wpisał '1'. Jedyny przypadek, w którym naprawdę robię wyjątek, to sytuacja, gdy konwertuję styl na liczbę, w takim przypadku parseFloatjest to pomocne, ponieważ style mają postać podobną do '3px', w którym to przypadku chcę porzucić 'px'część i po prostu uzyskać 3, więc uważam, że jest to parseFloatpomocne tutaj. Ale tak naprawdę to, który z nich wybierzesz, zależy od Ciebie i jakie formy danych wejściowych chcesz zaakceptować.

Zauważ, że użycie +operatora jednoargumentowego jest dokładnie tym samym, co użycie Numberjako funkcji:

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

Więc zwykle używam po prostu +w skrócie. Tak długo, jak wiesz, co robi, uważam, że jest łatwy do odczytania.


2
Nie uważałbym zachowania białych znaków => 0Number() za "dziwne". Nawet uznałbym je za bardziej oczekiwane, białe znaki to pusta wartość, ale nie są puste / nieokreślone => 0 to niezły wynik. W każdym razie duże (+) dla gablot :)
jave.web

4
@NathanWall: Może chciałbym o tym wspomnieć, Number('Infinity') === Infinitypodczas gdyparseInt('Infinity') === NaN
sstur

3
Nie +użyłbym w tym celu (jednoargumentowy plus), ponieważ jeśli zapomnisz średnika w poprzednim wierszu, zamiast tego może zostać obliczone wyrażenie dodające.
Jackson

1
W przypadkach, w których zachowują się tak samo, odkryłem, że parseFloat jest od 1% do 15% wolniejszy, a staje się wolniejszy, gdy wzrasta liczba cyfr dziesiętnych w ciągu. Z uruchomieniem 1M w moim systemie parseFloat („1.501”) jest o 5% wolniejsze niż Number („1.501”), a parseFloat („1.50137585467”) jest o 15% wolniejsze niż Number („1.50137585467”). Więc idę do Number ().
bytepan

1
@ ChrisBrownie55 Wow, dobry chwyt. Nie wiedziałem, że parseFloat może to zrobić. Myślę, że nieskończoność nie jest liczbą całkowitą!
sstur

9

Różnica polega na tym, co się dzieje, gdy dane wejściowe nie są „prawidłową liczbą”. Numberzwraca, NaNpodczas gdy parseFloatanalizuje „tyle, ile może”. Jeśli wywoływana na pustym ciągu Numberzwraca, 0podczas gdy parseFloat zwraca NaN.

Na przykład:

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

isNaN(Number("32f")) === true
parseFloat("32f") === 32

4
Zwróć NaN != NaNjednak uwagę
Wex

@Wex Och, myślisz, że NaN != NaNocena to PRAWDA - dzięki za wskazówkę!
jave.web

4
użyj isNaN () do testowania wartości NaN, isNaN(NaN)zwracatrue
jave.web

5

W tych przykładach widać różnicę:

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

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

parseFloat jest nieco wolniejszy, ponieważ wyszukuje pierwsze wystąpienie liczby w ciągu, podczas gdy konstruktor Number tworzy nową instancję liczby z ciągów zawierających wartości liczbowe z białymi znakami lub zawierające wartości fałszywe.

PS Jeśli interesują Cię uniwersalne rozwiązania do konwersji typów, możesz przeczytać wpis o konwersji typów na moim blogu: http://justsimplejs.blogspot.com/2012/08/data-type-conversion.html


2

W przypadku pustego ciągu są różne.

+""i Number("")zwraca 0, a parseFloat("")zwraca NaN.


2
Posunąłbym się nawet do stwierdzenia, że parseFloat()ma prawidłowy wynik, ponieważ pusty ciąg NIE jest liczbą 0(czytaj: NaN), podczas gdy łańcuch zawierający znak "0"JEST 0;
Christopher

+xzwraca 0nie tylko pusty ciąg, ale także dowolne białe znaki. Przykłady: +" ", +"\t\t\t", +"\n\n"- wszyscy z nich daje 0w wyniku
Łukasz Wiktor

2

O ile wiem, a to tylko słyszane przez kolegów, więc może być całkowicie źle poinformowany, że parseFloat jest nieznacznie szybszy.

Chociaż po dalszych badaniach wydaje się, że ta różnica w wydajności zależy od przeglądarki.

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

Spójrz na te wyniki jsPerf i zadzwoń. (zawiera również testy + x)

Jak zauważono w odpowiedzi @xdazz, +""and Number("")return 0while parseFloat("")zwraca, NaNwięc Znowu skorzystałbym z parseFloat, ponieważ pusty ciąg NIE oznacza liczby 0, tylko ciąg zawierający znak "0"oznacza 0;


Oto bardziej wyczerpujący test łowienia na szybszy sposób na konwersję ... parseFloat()nadal jest zwycięzcą.
mindplay.dk
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.