JavaScript'in parseInt sekizli davranışı etrafında nasıl çalışabilirim?


283

JavaScript'te aşağıdakileri çalıştırmayı deneyin:

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 !!

Sadece JavaScript lider sıfır bir işaret düşündüğünü zor yoldan öğrendim sekizlik tamsayı ve hiçbir olmadığından "8"veya "9"baz-8'de, işlev sıfırla döner. Beğen ya da beğenme, bu tasarım gereğidir .

Geçici çözümler nelerdir?

Not: Tamlık uğruna, bir çözüm göndermek üzereyim, ancak bu nefret ettiğim bir çözüm, bu yüzden lütfen başka / daha iyi cevaplar gönderin.


Güncelleme:

JavaScript standardının 5. Basımı ( ECMA-262 ) bu davranışı ortadan kaldıran bir değişiklik getirmektedir. Mozilla iyi sahiptir değer artışı .


21
Adım 1) Kendinize bir iyilik yapın ve her zaman önceki cevaplarda ve Doug'un kitabında belirtildiği gibi sayı tabanı ekleyin. Adım 2) JavaScript öğrenme konusunda ciddi iseniz, kendinize Doug'un kitabının bir kopyasını alın. Bu paha biçilemez. Benim favori kitabım. İşte bir inceleme fyi
fuentesjr

8
Internet Explorer 9, taban parametre varsayılan olarak ECMAScript 5th Edition uyumlu tarayıcılar, içinde 10ayrıştırma numara öneki sürece (ondalık) 0xörneğin 0xFF, bu durumda 16. Umarım, bir gün, bu konuya taban parametre varsayılan içinde uzak bir hafıza olacak.
Andy E

2
Sadece nasıl +'08' === 8? Doğru! Belki de parseIntgerçek kodunuz için gerçekten ihtiyacınız var , ancak yukarıdakiler için değil.
kojiro

1
a) bu bir hata değil, başlığını düzeltin b)Number('08')
OnTheFly

4
@portman: "5th Edition ... ortadan kaldırır bu davranış bir kırılma değişikliği tanıtır" : (13 yıl önce) bile 3 baskısında dışarı Muhtemelen değerinde işaret, uygulamalar bunu yapmak için değil "teşvik" bulundu "sayı tabanı olduğunda 0veya undefinedve dizenin numarası 0bir xveya tarafından takip edilmeyen bir rakamla başlar X, ardından uygulama kendi takdirine göre sayıyı sekizli veya ondalık olarak yorumlayabilir. Bu durumda sayıları ondalık olarak yorumlamaya teşvik edilir. " ( benim vurgu)
TJ Crowder

Yanıtlar:


329

Bu basit bir çözüm ile ortak bir Javascript gotcha olduğunu:

Yalnızca tabanı veya 'sayı tabanı ' belirtin, şöyle:

parseInt('08',10); // 8

Ayrıca kullanabilirsiniz Numarası :

Number('08'); // 8

57
Sayı . Şanlı.
Portman

10
Sayı, 08 civarında fiyat tekliflerine ihtiyaç duymaktadır. Ayrıca, uyarılmalıdır, Sayı ('08 .123 ') çıktı olarak 8.123 üretecektir. Gerçekten bir tamsayı istiyorsanız Sayı kullanmayın (veya yalnızca tamsayıları sağlamak için girdinizle desen eşleştirin).
Jason S

3
Numara (08); Firefox ve IE'de 8 veriyor.
Paolo Bergantino

3
ECMAscript standardının bir parçası değildir. Spidermonkey 1.7 (= Firefox JS motoru) kullanan ve "08 yasal bir ECMA-262 sekizli sabiti değil" şikayet ediyor JSDB üzerinde test ediyorum
Jason S

5
Yine de, tırnak işaretleri içinde '08' kullanın. 08, ECMA-262 standardını karşılamaz ve uyarılar ve / veya hatalar ve / veya belirli bir davranış olmadan başarılı olacağı garanti edilmez.
Jason S

43

Eğer varsa bilmek değerinizi imzalı 32 bitlik tamsayı aralığında olacak, o zaman ~~xbütün senaryolarda doğru olanı yapacağız.

~~"08" === 8
~~"foobar" === 0
~~(1.99) === 1
~~(-1.99)  === -1

İkili not ( ~) ifadesine bakarsanız , spec bir Int32'ye açık dönüşüm yapan ve NaNdeğerleri sıfıra zorlamak için belirtilen bağımsız değişken için bir "ToInt32" dönüşümü gerektirir .

Evet, bu inanılmaz derecede hackish ama çok uygun ...


2
Bir ikili veya yeterli olduğunda neden iki işlem?
Oleg V.Volkov

@Oleg, Neden biri yeterli olur?
Sebastian

3
@SebastianGodelet, | 0.
Oleg V.Volkov

@Grodriguez ve | 0 içinde 0 bir dize olduğunda?
Oleg

Bu soru, dizeleri tamsayılara dönüştürmek için parseInt alternatifleriyle ilgilidir. Böylece: her zaman.
Grodriguez

24

Gönderen parseInt belgelerinde , 10 tabanlı belirtmek üzere isteğe bağlı sayı tabanı argümanı kullanın:

parseInt('08', 10); //equals 8
parseInt('09', 10); //equals 9

Bu bana bilgiçlik taslayan, kafa karıştırıcı ve ayrıntılı (gerçekten, her bir ayrıştırmada fazladan bir argüman mı?)


6
Eğer Verbosity'i Sevmiyorsanız, yerleşik işlevi çağıran ve her zaman sabit tuttuğunuz argümanları dolduran kendi işlevinizi yapın.
Jason S

3
Riiiiiiight, çünkü StackOverflow'daki her bir kişi parseIntB10 işlevini yazmak için sizi rahatsız edecek gibi değil. Kendi sarmalayıcı işlevinizi yazmak bu amaç için korkunç bir fikirdir.
Stefan Kendall

2
@iftrue: Sanırım benim fikrimi kaçırdın. Şahsen ben taban 10'u zorladığımdan emin olmak için her yerde parseInt (someString, 10) yapmayı umursamıyorum. OP bu yaklaşımı beğenmiyor gibi görünüyor, bu yüzden kişisel olarak kullanamayacağım bir alternatif önerdim ama belki de onunla tanışıyor. ihtiyacı vardır. (Bu görünüşe göre JQuery arkasındaki düşünce: Ekstra karmaşıklık ekleyerek rahat olun. JQuery kullanmıyorum ama birçok kişi yararlı buluyorum.)
Jason S

4
Aslında parseInt, işlevsel ifadelerde rahat kullanım için sarmak gerçekten önemlidir , çünkü mapiçinde dizideki öğenin dizinini , ikinci argüman olarak ["7","4","09","5"].map(parseInt); Mapgeçirirsiniz; bu, siz kaydırmadıkça temel olarak yorumlanır . parseInt
Plynx

11
function parseDecimal(s) { return parseInt(s, 10); }

edit: kendi fonksiyonunuzu yapmak, gerçekten ne istediğinizi yapmak, sadece parseInt () çağrısına her zaman ", 10" eklemek istemiyorsanız bir seçenektir. Standart olmayan bir işlev olmanın dezavantajı vardır: çok kullanırsanız sizin için daha uygun, ancak belki de diğerleri için daha kafa karıştırıcıdır.


10

Tabanı belirtin:

var number = parseInt(s, 10);

Vay canına siz hızlısınız. Cevabımı panoda bile aldım. Doğrudan İnternet'e bağlı mısınız, Neo tarzı?
Portman

1
Şeytan neden bu tabanın 10 varsayılan ayarı değil
Tom Gullen

2
Belki de esas olarak bir String-> Number dönüştürme işlevi değil, temel sayı b String'den bir Sayı okuyan bir işlev anlamına gelir.
artistoex

2
varsayılan olarak 10 tabanına ayarlıdır, ancak baştaki sıfırlar sekizli belirtmenin yaygın bir yoludur.
Nathan

7

ParseInt öğesini, ikinci parametresi yoksa ondalık sayılacak bir sürümle değiştirmek çok yaramaz mı? (not - test edilmedi)

parseIntImpl = parseInt
parseInt = function(str, base){return parseIntImpl(str, base ? base : 10)}

2
evet, bu yaramaz olurdu - standart davranışa dayanan diğer kodu kıracaktır.
jes5199

4
Bu doğru, ama fazla bir şey yok. Ayrıca standart davranış değildir - sekizli destek isteğe bağlıdır.
Andrew Duffy

2
Ancak isteğe bağlı olmayan altıgen desteği de bırakıyorsunuz, değil mi? Bu her zaman doğru olmalıdır:, parseInt("0xFFFFFF") === 16777215ama yaramaz kesmek yerine artık çalışmıyorparseInt("0xFFFFFF") === 0
Timo


6

Ayrıca, parseFloat veya parseInt yerine tekli işleci ( + ) kullanabilirsiniz.

+"01"
// => 1

+"02"
// => 2

+"03"
// => 3

+"04"
// => 4

+"05"
// => 5

+"06"
// => 6

+"07"
// => 7

+"08"
// => 8

+"09"
// => 9

ve iyi bir ölçü için

+"09.09"
// => 9.09

MDN Bağlantısı

Tekli artı işleci işleneninden önce gelir ve işlenenini değerlendirir, ancak henüz değilse bir sayıya dönüştürmeye çalışır. Her ne kadar tekli olumsuzlama (-) sayı olmayanları da dönüştürebilirse de, tekli artı bir şeyi sayıya dönüştürmenin en hızlı ve tercih edilen yoludur , çünkü sayı üzerinde başka bir işlem yapmaz.


5

Ondalık için buna ne dersiniz:

('09'-0) === 9  // true

('009'-0) === 9 // true

4

ParseInt ile zaten bir grup kodlama yaptıysanız ve her şeye ", 10" eklemek istemiyorsanız, temel 10'u varsayılan yapmak için işlevi geçersiz kılabilirsiniz:

window._oldParseInt = window.parseInt;
window.parseInt = function(str, rad) {
    if (! rad) {
        return _oldParseInt(str, 10);
    }
    return _oldParseInt(str, rad);
};

Bu daha sonraki bir okuyucuyu karıştırabilir, bu nedenle bir parseInt10 () işlevi yapmak daha açıklayıcı olabilir. Şahsen ben her zaman ", 10" eklemek zorunda basit bir fonksiyon kullanmayı tercih - sadece hatalar için daha fazla fırsat yaratır.


0

Bu sorun en son Chrome'da veya Firefox'ta (2019) çoğaltılamaz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.