Javascript parseInt () mit führenden Nullen

118

Die parseInt-Funktion von Javascript scheint nicht vollständig zu funktionieren.

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

Das kannst du nicht erklären. Versuche es. (jsFiddle)

Bearbeiten Da diese Frage gestellt und beantwortet wurde, ist die "Funktion" der Standardeinstellung für Oktalradix veraltet. [ 1 ] [ 2 ]

Sparer
quelle
28
Sie müssen scherzen
Georg
6
You can't explain that. Ja, Sie können => developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
Rocket Hazmat
3
Seit dem Alter steht jede Zahl, die mit 0 beginnt, für OCTAL und 0x für Hexa-Dezimal. Ich glaube, dass dies für alle Sprachen universell ist, aber auch hier kann ich mich irren.
Selvakumar Arumugam
3
Zu Ihrer Information : jsFiddle ist ein besserer Online-JavaScript-Tester als w3schools.com/jsref/tryit.asp .
Rocket Hazmat
2
@ JohnHartsock Yeh, es ist, weil wir beide auf diesem Beitrag waren stackoverflow.com/questions/8761997/…
Retter

Antworten:

180

Dies liegt daran, dass eine Zahl, die mit einer '0' beginnt, als Basis 8 (oktal) behandelt wird.

Sie können die Basis erzwingen, indem Sie die Basis als 2. Parameter übergeben.

parseInt("09", 10) // 9

Gemäß den Dokumenten ist der 2. Parameter optional, es wird jedoch nicht immer angenommen, dass er 10 ist, wie Sie aus Ihrem Beispiel sehen können.

Rakete Hazmat
quelle
1
Ja, aber wenn es als oktal angenommen wird, sollte es 11 für 09 statt 0 zurückgeben.
Peeyush Kushwaha
2
@PeeyushKushwaha: Anders herum. 11in Basis 8 ist 9in Basis 10. 09ist keine gültige Basis 8-Nummer.
Rocket Hazmat
Aber ich möchte 09 nach parseInt, gibt es einen Ausweg
Pardeep Jain
39

Aufrufe von parseIntsollten im zweiten Argument immer eine Basis angeben:

parseInt("08", 10);

Frühere Versionen von JavaScript behandeln Zeichenfolgen, die mit 0oktal beginnen (wenn keine Basis angegeben ist) und weder 08noch 09gültige Oktalzahlen.

Aus der Mozilla- Dokumentation :

Wenn radix undefiniert oder 0 ist, nimmt JavaScript Folgendes an:

  • Wenn die Eingabezeichenfolge mit "0x" oder "0X" beginnt, ist der Radix 16 (hexadezimal).
  • Wenn die Eingabezeichenfolge mit "0" beginnt, ist der Radix acht (oktal). Diese Funktion ist nicht Standard und wird von einigen Implementierungen absichtlich nicht unterstützt (stattdessen wird der Radix 10 verwendet). Aus diesem Grunde immer eine Radix angeben , wenn ParseInt mit .
  • Wenn die Eingabezeichenfolge mit einem anderen Wert beginnt, beträgt der Radix 10 (dezimal).

Wenn das erste Zeichen nicht in eine Zahl konvertiert werden kann, gibt parseInt NaN zurück.

Und aus dem ECMAScript 3- Standard:

Wenn radix 0 oder undefiniert ist und die Nummer der Zeichenfolge mit einer 0- Ziffer beginnt, auf die kein x oder X folgt , kann die Implementierung die Nummer nach eigenem Ermessen entweder als oktal oder als dezimal interpretieren. Implementierungen werden empfohlen, Zahlen in diesem Fall als Dezimalzahlen zu interpretieren.

Die neueste Version von JavaScript ( ECMAScript 5 ) gibt dieses Verhalten auf , Sie sollten jedoch weiterhin den Radix angeben , um ältere Browser zufrieden zu stellen.

Wayne
quelle
Da dies veraltet ist, könnten Sie in Zukunft führende Nullen verwenden, nicht wahr?
Pacerier
15

Es gibt einen Radix-Parameter

parseInt(value, base)

Wo Basis ist der Radix.

In diesem Fall werten Sie Base10-Zahlen (Dezimalzahlen) aus. Verwenden Sie daher

parseInt(value, 10);
John Hartsock
quelle
4

Dies scheint in neuen Browsern nicht vollständig gültig zu sein. Internet Explorer 9 und 10 geben 8 zurück, wenn Sie 'parseInt ("08")' ausführen, während Internet Explorer 8 und frühere Versionen 0 zurückgeben (IE10 im Quirks-Modus gibt ebenfalls 0 zurück).

Die neueste Version von Chrome gibt auch 8 zurück, daher muss die Interpretation kürzlich geändert worden sein.

Maffelu
quelle
Ja, das Verhalten hat sich geändert. Ich werde meine Antwort aktualisieren. developer.mozilla.org/en-US/docs/JavaScript/Reference/…
Wayne
1
Ja, die neueste Version von Firefox und Chrome hat jetzt kein Problem.
mythicalcoder
3

Dieses Problem ist jetzt veraltet. Sie können jedoch weiterhin radix in verwenden parseInt, um die Anzahl anderer Basen in Base-10 umzuwandeln. Z.B,

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

gibt zurück 17(das ist Basis-10 von 0010001).

Muhammad Imran
quelle
0

Tipp: Wie Sie jetzt wissen, ist die Standardeinstellung für Oktal veraltet. Hier erfahren Sie, wie Sie das Problem in älteren Browsern beheben können

// 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));
}
Endlos
quelle
PS: Wenn Sie nur eine konstante Zahl mit einer führenden Null (anstelle einer Zeichenfolge) verwenden, wird diese in allen aktuellen Browsern weiterhin als Basis 8 behandelt.
Agamemnus
0

Das Problem scheint sich jetzt in den meisten Browsern geändert zu haben.

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

=====

Empfohlene Praxis

Um jedoch auf der sicheren Seite zu sein und Probleme zu vermeiden, verwenden Sie den Parameter base / radix, wie in der akzeptierten Antwort vorgeschlagen .

parseInt("09", 10)    // 9

Extra Test

Ich wollte das auch nur testen, wenn das Argument keine Zeichenfolge ist. Chrome & Safari liefert ein genaues Ergebnis. Auch Firefox liefert das richtige Ergebnis, jedoch mit einer Warnung.

parseInt(09)     // 9. (Warning: SyntaxError: 09 is not a legal ECMA-262 octal constant)
mythischer Kodierer
quelle
Wenn der Wert mit 0 beginnt und eine Zahl ist, verwendet parseInt weiterhin Basis 8. Versuchen Sie parseInt (020)
sirrocco
Ja. Ich habe sogar auf die vorgeschlagene Antwort hingewiesen. Und ich kenne Best Practices und schlechte Funktionen, die ich vermeiden sollte. Daher habe ich in meiner Antwort auch die empfohlene Praxis angegeben .
Mythicalcoder