Javascript parseInt () z zerami na początku


120

Wydaje się, że funkcja parseInt JavaScript nie działa całkowicie.

parseInt("01") returns 1
parseInt("02") returns 2
parseInt("03") returns 3
parseInt("04") returns 4
parseInt("05") returns 5
parseInt("06") returns 6
parseInt("07") returns 7
parseInt("08") returns 0
parseInt("09") returns 0

Nie możesz tego wyjaśnić. Spróbuj. (jsFiddle)

Edytuj Ponieważ zadano to pytanie i udzielono na nie odpowiedzi, „funkcja” domyślnej podstawy ósemkowej została wycofana. [ 1 ] [ 2 ]


29
chyba żartujesz
georg


3
Od wieków każda liczba zaczynająca się od 0 reprezentuje OCTAL, a 0x reprezentuje liczbę szesnastkową. Uważam, że jest to uniwersalne dla wszystkich języków, ale znowu mogę się mylić.
Selvakumar Arumugam

3
FYI: jsFiddle , jest lepszym testerem JavaScript online niż w3schools.com/jsref/tryit.asp .
Rocket Hazmat

2
@JohnHartsock Tak, to dlatego, że obaj byliśmy na tym poście stackoverflow.com/questions/8761997/ ...
oszczędzam

Odpowiedzi:


181

Dzieje się tak, ponieważ jeśli liczba zaczyna się od „0”, jest traktowana jako podstawa 8 (ósemkowa).

Możesz wymusić podstawę, przekazując podstawę jako drugi parametr.

parseInt("09", 10) // 9

Zgodnie z dokumentacją , drugi parametr jest opcjonalny, ale nie zawsze przyjmuje się, że wynosi 10, jak widać na przykładzie.


1
tak, ale jeśli przyjmie się
liczbę ósemkową

2
@PeeyushKushwaha: Inaczej. 11o podstawie 8 jest o 9podstawie 10. 09nie jest prawidłową liczbą o podstawie 8.
Rocket Hazmat

Ale chcę 09 po przeanalizowaniu, czy jest jakikolwiek sposób
Pardeep Jain

39

Wywołania do parseIntpowinny zawsze określać podstawę w drugim argumencie:

parseInt("08", 10);

Wcześniejsze wersje JavaScript traktują ciągi zaczynające się od 0jako ósemkowe (gdy nie określono podstawy) i ani 08nie 09są one poprawnymi liczbami ósemkowymi.

Z dokumentacji Mozilli :

Jeśli podstawa jest niezdefiniowana lub 0, JavaScript zakłada, co następuje:

  • Jeśli ciąg wejściowy zaczyna się od „0x” lub „0X”, podstawa wynosi 16 (szesnastkowo).
  • Jeśli ciąg wejściowy zaczyna się od „0”, podstawa to osiem (ósemkowa). Ta funkcja jest niestandardowa i niektóre implementacje celowo jej nie obsługują (zamiast tego używają radix 10). Z tego powodu zawsze określaj podstawę, gdy używasz parseInt .
  • Jeśli ciąg wejściowy zaczyna się od dowolnej innej wartości, podstawa wynosi 10 (dziesiętnie).

Jeśli pierwszego znaku nie można przekonwertować na liczbę, parseInt zwraca NaN.

I ze standardu ECMAScript 3 :

Gdy podstawa jest równa 0 lub nieokreślona, a numer ciągu zaczyna się od cyfry 0, po której nie następuje znak x lub X , implementacja może, według własnego uznania, zinterpretować liczbę jako liczbę ósemkową lub dziesiętną. Zachęca się implementacje do interpretowania liczb w tym przypadku jako dziesiętnych.

Najnowsza wersja JavaScript ( ECMAScript 5 ) porzuca to zachowanie , ale nadal należy określić podstawę, aby zadowolić starsze przeglądarki.


Ponieważ jest to przestarzałe, w przyszłości byłoby dobrze, gdybyś używał zer wiodących, prawda?
Pacerier

15

Istnieje parametr Radix

parseInt(value, base)

Gdzie podstawa jest podstawą.

W tym przypadku obliczasz liczby dziesiętne (dziesiętne), dlatego użyj

parseInt(value, 10);

4

Wydaje się, że nie działa to całkowicie w nowych przeglądarkach. Internet Explorer 9 i 10 zwróci 8, jeśli wykonasz 'parseInt ("08")', podczas gdy Internet Explorer 8 i poprzednie wersje zwrócą 0 (IE10 w trybie dziwactw również zwróci 0).

Najnowsza wersja Chrome również zwraca 8, więc musieli ostatnio zmienić interpretację.


Tak, zachowanie się zmieniło. Zaktualizuję odpowiedź. developer.mozilla.org/en-US/docs/JavaScript/Reference/…
Wayne

1
Tak, najnowsza wersja przeglądarek Firefox i Chrome nie ma teraz problemu.
mythicalcoder

3

Ten problem jest teraz przestarzały. Ale nadal możesz użyć radix in, parseIntaby przekonwertować liczbę innych zasad na podstawę-10. Na przykład,

var baseTwoNumber = parseInt('0010001', 2);

zwraca 17(czyli podstawa-10 z 0010001).


0

Wskazówka: jak już wiesz, kiedy default to ósemkowy został wycofany. Oto, jak można to naprawić w starszych przeglądarkach

// ES-5 15.1.2.2
if (parseInt('08') !== 8 || parseInt('0x16') !== 22) {
    parseInt = (function (origParseInt) {
        var hexRegex = /^0[xX]/;
        return function parseIntES5(str, radix) {
            str = String(str).trim();
            if (!Number(radix)) {
                radix = hexRegex.test(str) ? 16 : 10;
            }
            return origParseInt(str, radix);
        };
    }(parseInt));
}

PS: jeśli używasz tylko stałej liczby z wiodącym zerem (zamiast ciągu), jest ona nadal traktowana jako podstawa 8 we wszystkich obecnych przeglądarkach.
Agamemnus

0

Wydaje się, że problem zmienił się teraz w większości przeglądarek.

Firefox 51.0.1 (64-bitowy)

parseInt("09")   // 9

Chrome 55.0.2883.95 (64-bitowy)

parseInt("09")   // 9

Safari 10.0 (12602.1.50.0.10)

parseInt("09")   // 9

=====

Zalecana praktyka

To powiedziawszy, aby być bezpieczniejszym i uniknąć problemów, użyj parametru base / radix zgodnie z sugestią zawartą w zaakceptowanej odpowiedzi .

parseInt("09", 10)    // 9

Dodatkowy test

Chciałem to również przetestować, jeśli argument nie jest łańcuchem. Chrome i Safari dają dokładny wynik. Firefox również zwraca prawidłowy wynik, ale z ostrzeżeniem.

parseInt(09)     // 9. (Warning: SyntaxError: 09 is not a legal ECMA-262 octal constant)

Jeśli wartość zaczyna się od 0 i jest liczbą, parseInt nadal będzie używać podstawy 8. Spróbuj parseInt (020)
sirrocco

Tak. Wskazałem nawet na sugerowaną odpowiedź. Znam sprawdzone metody i złe funkcje, których należy unikać. Tak więc w mojej odpowiedzi podałem również Zalecaną praktykę .
mythicalcoder
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.