Javascript parseInt () con zeri iniziali


120

La funzione parseInt di Javascript non sembra funzionare completamente.

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

Non puoi spiegarlo. Provaci. (jsFiddle)

Modifica Dal momento che questa domanda è stata posta e ha risposto, la "funzionalità" di default per la radice ottale è stata deprecata. [ 1 ] [ 2 ]


29
stai scherzando
georg


3
Da età, qualsiasi numero che inizia con 0 rappresenta OTTALE e 0x rappresenta esadecimale. Credo che questo sia universale per tutte le lingue, ma ancora una volta potrei sbagliarmi.
Selvakumar Arumugam

3
FYI: jsFiddle , è un tester JavaScript online migliore di w3schools.com/jsref/tryit.asp .
Rocket Hazmat

2
@JohnHartsock Yeh, è perché eravamo entrambi su questo post stackoverflow.com/questions/8761997/...
savinger

Risposte:


181

Questo perché se un numero inizia con uno "0", viene considerato come base 8 (ottale).

È possibile forzare la base passando la base come 2 ° parametro.

parseInt("09", 10) // 9

Secondo la documentazione , il secondo parametro è facoltativo, ma non si presume sempre che sia 10, come puoi vedere dal tuo esempio.


1
sì, ma se si presume ottale, dovrebbe restituire 11 per 09 invece di 0.
Peeyush Kushwaha

2
@ PeeyushKushwaha: Al contrario. 11in base 8 è 9in base 10. 09non è un numero in base 8 valido.
Rocket Hazmat

Ma voglio 09 dopo parseInt, c'è un modo per aggirare
Pardeep Jain

39

Le chiamate a parseIntdovrebbero sempre specificare una base nel secondo argomento:

parseInt("08", 10);

Le versioni precedenti di JavaScript trattano le stringhe che iniziano con 0come ottale (quando non è specificata alcuna base) e né 0809sono numeri ottali validi.

Dalla documentazione di Mozilla :

Se radix è undefined o 0, JavaScript presuppone quanto segue:

  • Se la stringa di input inizia con "0x" o "0X", la radice è 16 (esadecimale).
  • Se la stringa di input inizia con "0", la radice è otto (ottale). Questa caratteristica non è standard e alcune implementazioni deliberatamente non la supportano (usando invece il radix 10). Per questo motivo, specificare sempre una radice quando si usa parseInt .
  • Se la stringa di input inizia con qualsiasi altro valore, la radice è 10 (decimale).

Se il primo carattere non può essere convertito in un numero, parseInt restituisce NaN.

E dallo standard ECMAScript 3 :

Quando radix è 0 o indefinito e il numero della stringa inizia con una cifra 0 non seguita da x o X , l'implementazione può, a sua discrezione, interpretare il numero come ottale o decimale. Le implementazioni sono incoraggiate a interpretare i numeri in questo caso come decimali.

L'ultima versione di JavaScript ( ECMAScript 5 ) abbandona questo comportamento , ma dovresti comunque specificare la radice per soddisfare i browser meno recenti.


Dato che questo è deprecato, in futuro staresti bene con l'uso degli zeri iniziali, no?
Pacerier

15

C'è un parametro Radix

parseInt(value, base)

Dove la base è la radice.

In questo caso stai valutando i numeri in base10 (decimali), quindi usa

parseInt(value, 10);

4

Questo non sembra essere completamente valido nei nuovi browser. Internet Explorer 9 e 10 restituirà 8 se esegui 'parseInt ("08")' mentre Internet Explorer 8 e le versioni precedenti restituiranno 0 (anche IE10 in modalità quirks restituirà 0).

L'ultima versione di Chrome restituisce anche 8, quindi devono aver cambiato l'interpretazione di recente.


Sì, il comportamento è cambiato. Aggiornerò la mia risposta. developer.mozilla.org/en-US/docs/JavaScript/Reference/…
Wayne

1
Sì, l'ultima versione di Firefox e Chrome non ha problemi ora.
mythicalcoder

3

Questo problema è ora deprecato. Ma puoi ancora usare radix in parseIntper convertire il numero di altre basi in base 10. Per esempio,

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

restituisce 17(che è in base 10 di 0010001).


0

Suggerimento: come ora sai quando il valore predefinito di ottale è stato deprecato. Ecco come risolverlo nei browser legacy

// 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: se usi solo un numero costante con uno zero iniziale (invece di una stringa), viene comunque considerato come base 8 in tutti i browser correnti.
Agamemnus

0

Il problema sembra essere cambiato ora nella maggior parte dei browser.

Firefox 51.0.1 (64 bit)

parseInt("09")   // 9

Chrome 55.0.2883.95 (64 bit)

parseInt("09")   // 9

Safari 10.0 (12602.1.50.0.10)

parseInt("09")   // 9

=====

Pratica consigliata

Detto questo, solo per essere più sicuri ed evitare problemi, utilizzare il parametro base / radix come suggerito nella risposta accettata .

parseInt("09", 10)    // 9

Test extra

Volevo solo testare anche questo, se l'argomento non è una stringa. Chrome e Safari danno il risultato esatto. Anche Firefox restituisce un risultato corretto, ma con un avviso.

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

Se il valore inizia con 0 ed è un numero, parseInt utilizzerà comunque la base 8. Prova parseInt (020)
sirrocco

Sì. Ho anche indicato la risposta suggerita. E conosco le migliori pratiche e le cattive caratteristiche da evitare. Quindi ho fornito anche la pratica consigliata nella mia risposta.
mythicalcoder
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.