Spróbuj wykonać następujące czynności w 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 !!
Właśnie dowiedziałem się na własnej skórze, że JavaScript uważa, że zera wskazuje ósemkowy całkowitą , a ponieważ nie jest "8"
ani "9"
w bazie-8, funkcja zwraca zero. Czy ci się to podoba, czy nie, jest to zgodne z projektem .
Jakie są obejścia?
Uwaga: Ze względu na kompletność, zamierzam opublikować rozwiązanie, ale nienawidzę tego rozwiązania, więc proszę o publikowanie innych / lepszych odpowiedzi.
Aktualizacja:
Piąta edycja standardu JavaScript ( ECMA-262 ) wprowadza przełomową zmianę, która eliminuje to zachowanie. Mozilla ma dobre write-up .
javascript
integer
octal
Portman
źródło
źródło
10
(dziesiętną), chyba że przed analizowanym numerem jest poprzedzony0x
np.0xFF
W takim przypadku parametr podstawowy ma wartość 16. Mam nadzieję, że pewnego dnia ten problem będzie odległym wspomnieniem.+'08' === 8
? Prawdziwe! Może naprawdę potrzebujeszparseInt
prawdziwego kodu, ale nie powyższego.Number('08')
0
lubundefined
a liczba łańcucha rozpoczyna się0
cyfrą, po której nie następuje znak „x
lub”X
, a następnie implementacja może, według własnego uznania, interpretować liczbę jako ósemkową lub dziesiętną. Zachęca się implementacje do interpretowania liczb w tym przypadku jako dziesiętnych. ” ( mój nacisk)Odpowiedzi:
Jest to typowa gotcha JavaScript z prostym rozwiązaniem:
Po prostu określ podstawę lub „radix”, tak jak poniżej:
Możesz także użyć numeru :
źródło
Jeśli wiesz , że twoja wartość będzie w zakresie 32-bitowych liczb całkowitych ze znakiem,
~~x
zrobi to poprawnie we wszystkich scenariuszach.Jeśli spojrzysz na binarną not (
~
), specyfikacja wymaga konwersji „ToInt32” dla argumentu, który dokonuje oczywistej konwersji na Int32 i jest określony w celu wymuszeniaNaN
wartości na zero.Tak, to jest niesamowicie hackerskie, ale jest tak wygodne ...
źródło
W dokumentacji parseInt użyj opcjonalnego argumentu Radix, aby określić base-10:
Wydaje mi się to pedantyczne, mylące i pełne słów (tak naprawdę dodatkowy argument w każdej analizie?), Więc mam nadzieję, że istnieje lepszy sposób.
źródło
parseInt
dla wygodnego użycia w wyrażeniach funkcjonalnych, tak jakmap
in["7","4","09","5"].map(parseInt);
Map
przekazuje indeks elementu w tablicy jako drugi argument, który będzie interpretowanyparseInt
jako podstawa, chyba że go zawiniesz.edit: tworzenie własnej funkcji, aby robić to, czego naprawdę chcesz, to tylko opcja, jeśli nie lubisz dodawać „, 10” przez cały czas do wywołania parseInt (). Ma tę wadę, że jest niestandardową funkcją: wygodniejszą dla Ciebie, jeśli często z niej korzystasz, ale być może bardziej mylącą dla innych.
źródło
Określ podstawę:
źródło
Czy bardzo niegrzeczne byłoby zastąpienie parseInt wersją, która przyjmuje liczbę dziesiętną, jeśli nie ma drugiego parametru? (uwaga - nie testowano)
źródło
parseInt("0xFFFFFF") === 16777215
ale z twoim niegrzecznym włamaniem nie działa jużparseInt("0xFFFFFF") === 0
i na wszelki wypadek
Link MDN
źródło
Co powiesz na dziesiętny:
źródło
Jeśli wykonałeś już sporo kodowania za pomocą parseInt i nie chcesz dodawać „, 10” do wszystkiego, możesz po prostu przesłonić funkcję, aby ustawić domyślną bazę 10:
To może mylić późniejszego czytnika, więc wykonanie funkcji parseInt10 () może być bardziej zrozumiałe. Osobiście wolę używać prostej funkcji niż ciągłe dodawanie „, 10” - po prostu stwarza więcej okazji do błędów.
źródło
Tego problemu nie można replikować w najnowszym Chrome ani Firefox (2019).
źródło