Coba jalankan yang berikut dalam 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 !!
Saya baru belajar dengan susah payah bahwa JavaScript menganggap nol di depan menunjukkan integer oktal , dan karena tidak ada "8"
atau "9"
di basis-8, fungsi mengembalikan nol. Suka atau tidak, ini sesuai desain .
Apa solusinya?
Catatan: Demi kelengkapan, saya akan memposting solusi, tapi ini solusi yang saya benci, jadi tolong posting jawaban lain / lebih baik.
Memperbarui:
Edisi 5 dari standar JavaScript ( ECMA-262 ) memperkenalkan perubahan besar yang menghilangkan perilaku ini. Mozilla memiliki yang baik write-up .
javascript
integer
octal
Portman
sumber
sumber
10
(desimal) kecuali angka yang diurai diawali dengan0x
, misalnya0xFF
, dalam hal ini parameter dasar default ke 16. Mudah-mudahan, suatu hari, masalah ini akan menjadi memori yang jauh.+'08' === 8
? Benar! Mungkin Anda benar-benar membutuhkanparseInt
kode asli Anda, tetapi tidak untuk yang di atas.Number('08')
0
atauundefined
dan nomor string dimulai dengan0
digit yang tidak diikuti olehx
atauX
, maka implementasinya dapat, dengan kebijakannya sendiri, menginterpretasikan angka tersebut sebagai oktal atau sebagai desimal. Implementasi didorong untuk menafsirkan angka dalam kasus ini sebagai desimal. " ( Penekanan saya)Jawaban:
Ini adalah gotcha Javascript yang umum dengan solusi sederhana:
Cukup tentukan basisnya , atau 'radix', seperti:
Anda juga bisa menggunakan Nomor :
sumber
Jika Anda tahu nilai Anda akan berada dalam rentang integer 32 bit yang ditandatangani, maka
~~x
akan melakukan hal yang benar di semua skenario.Jika Anda mencari biner bukan (
~
), spesifikasi memerlukan konversi "ToInt32" untuk argumen yang melakukan konversi yang jelas ke Int32 dan ditentukan untuk memaksaNaN
nilai menjadi nol.Ya, ini sangat hackish tetapi sangat nyaman ...
sumber
Dari dokumentasi parseInt , gunakan argumen radix opsional untuk menentukan basis-10:
Ini menurut saya pedantic, membingungkan, dan bertele-tele (sungguh, argumen tambahan di setiap parseInt?) Jadi saya berharap ada Cara yang Lebih Baik.
sumber
parseInt
agar nyaman digunakan dalam ekspresi fungsional, sepertimap
pada["7","4","09","5"].map(parseInt);
Map
akan melewati indeks elemen dalam array sebagai argumen kedua, yang akan ditafsirkanparseInt
sebagai basis kecuali jika Anda membungkusnya.sunting: membuat fungsi Anda sendiri, untuk melakukan apa yang benar-benar Anda inginkan, hanyalah sebuah opsi jika Anda tidak suka menambahkan panggilan ", 10" sepanjang waktu ke panggilan parseInt (). Ini memiliki kelemahan menjadi fungsi yang tidak standar: lebih nyaman bagi Anda jika Anda sering menggunakannya, tetapi mungkin lebih membingungkan bagi orang lain.
sumber
Tentukan basisnya:
sumber
Apakah akan sangat nakal untuk mengganti parseInt dengan versi yang mengasumsikan desimal jika tidak memiliki parameter kedua? (catatan - tidak diuji)
sumber
parseInt("0xFFFFFF") === 16777215
tetapi dengan hack nakal Anda di tempat itu tidak lagi berfungsiparseInt("0xFFFFFF") === 0
dan untuk ukuran yang baik
MDN Link
sumber
Bagaimana dengan ini untuk desimal:
sumber
Jika Anda sudah melakukan banyak pengkodean dengan parseInt dan tidak ingin menambahkan ", 10" ke semuanya, Anda bisa mengganti fungsi untuk menjadikan basis 10 sebagai default:
Itu mungkin membingungkan pembaca kemudian, jadi membuat fungsi parseInt10 () mungkin lebih jelas. Secara pribadi saya lebih suka menggunakan fungsi sederhana daripada harus menambahkan ", 10" sepanjang waktu - hanya menciptakan lebih banyak peluang untuk kesalahan.
sumber
Masalah ini tidak dapat direplikasi di Chrome terbaru atau Firefox (2019).
sumber