Javascript parseInt () với các số 0 ở đầu


120

Hàm parseInt của Javascript dường như không hoàn toàn hoạt động.

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

Bạn không thể giải thích điều đó. Hãy thử một lần. (jsFiddle)

Chỉnh sửa Vì câu hỏi này đã được hỏi và trả lời, nên "tính năng" mặc định cho cơ số bát phân đã không còn được dùng nữa. [ 1 ] [ 2 ]


29
chắc bạn đang đùa
georg

6
You can't explain that. Có, bạn có thể => developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
Rocket Hazmat

3
Kể từ độ tuổi, bất kỳ số nào bắt đầu bằng 0 đại diện cho OCTAL và 0x đại diện cho hệ thập lục phân. Tôi tin rằng điều này là phổ biến cho tất cả các ngôn ngữ, nhưng một lần nữa tôi có thể sai.
Selvakumar Arumugam

3
FYI: jsFiddle , là trình kiểm tra JavaScript trực tuyến tốt hơn w3schools.com/jsref/tryit.asp .
Rocket Hazmat

2
@JohnHartsock Yeh, đó là bởi vì cả hai chúng tôi đều ở trên bài đăng này stackoverflow.com/questions/8761997/…
saveer

Câu trả lời:


181

Điều này là do nếu một số bắt đầu bằng '0', nó được coi là cơ số 8 (bát phân).

Bạn có thể buộc cơ sở bằng cách chuyển cơ sở làm tham số thứ 2.

parseInt("09", 10) // 9

Theo tài liệu , tham số thứ 2 là tùy chọn, nhưng nó không phải lúc nào cũng được giả định là 10, như bạn có thể thấy từ ví dụ của mình.


1
yeah, nhưng nếu nó được giả định bát phân, nó phải được trở về 11 cho 09 thay vì 0.
Peeyush Kushwaha

2
@PeeyushKushwaha: Ngược lại. 11trong cơ số 8 là 9cơ số 10. 09không phải là cơ số 8 hợp lệ.
Rocket Hazmat

Nhưng tôi muốn 09 sau parseInt, có cách nào để khắc phục
Pardeep Jain

39

Các lệnh gọi tới parseIntphải luôn chỉ định một cơ sở trong đối số thứ hai:

parseInt("08", 10);

Các phiên bản JavaScript trước đây coi các chuỗi bắt đầu bằng số 0bát phân (khi không có cơ số nào được chỉ định) và không 08phải 09là số bát phân hợp lệ.

Từ tài liệu Mozilla :

Nếu cơ số là không xác định hoặc 0, JavaScript sẽ giả định như sau:

  • Nếu chuỗi đầu vào bắt đầu bằng "0x" hoặc "0X", cơ số là 16 (hệ thập lục phân).
  • Nếu chuỗi đầu vào bắt đầu bằng "0", cơ số là tám (bát phân). Tính năng này không phải là tiêu chuẩn và một số triển khai cố tình không hỗ trợ tính năng này (thay vào đó sử dụng cơ số 10). Vì lý do này, luôn chỉ định một cơ số khi sử dụng parseInt .
  • Nếu chuỗi nhập bắt đầu bằng bất kỳ giá trị nào khác, cơ số là 10 (thập phân).

Nếu ký tự đầu tiên không thể được chuyển đổi thành một số, parseInt trả về NaN.

Và từ tiêu chuẩn ECMAScript 3 :

Khi cơ số là 0 hoặc không xác định và số của chuỗi bắt đầu bằng chữ số 0, không theo sau là x hoặc X , thì việc triển khai có thể, theo quyết định của mình, giải thích số là số bát phân hoặc là số thập phân. Việc triển khai được khuyến khích để giải thích các số trong trường hợp này là số thập phân.

Phiên bản JavaScript mới nhất ( ECMAScript 5 ) loại bỏ hành vi này , nhưng bạn vẫn nên chỉ định cơ số để đáp ứng các trình duyệt cũ hơn.


Vì điều này không còn được dùng nữa, nên trong tương lai, bạn sẽ ổn khi sử dụng các số 0 ở đầu phải không?
Pacerier

15

Có một tham số Radix

parseInt(value, base)

Trong đó cơ số là cơ số.

Trong trường hợp này, bạn đang đánh giá các số cơ số 10 (thập phân), do đó hãy sử dụng

parseInt(value, 10);

4

Điều này dường như không hoàn toàn hợp lệ trong các trình duyệt mới. Internet Explorer 9 và 10 sẽ trả về 8 nếu bạn thực thi 'parseInt ("08")' trong khi Internet Explorer 8 và các phiên bản trước sẽ trả về 0 (IE10 ở chế độ quirks cũng sẽ trả về 0).

Phiên bản mới nhất của Chrome cũng trả về 8 vì vậy gần đây họ phải thay đổi cách diễn giải.


Đúng, hành vi đã thay đổi. Tôi sẽ cập nhật câu trả lời của tôi. developer.mozilla.org/en-US/docs/JavaScript/Reference/…
Wayne

1
Có, Firefox và Chrome phiên bản mới nhất hiện không gặp sự cố.
mythicalcoder

3

Vấn đề này hiện không được dùng nữa. Nhưng bạn vẫn có thể sử dụng cơ số trong parseIntđể chuyển đổi số cơ số khác thành cơ số 10. Ví dụ,

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

trả về 17(là cơ số 10 của 0010001).


0

Mẹo: Như bạn đã biết khi nào mặc định thành bát phân không được dùng nữa. Đây là cách bạn sẽ sửa nó trong các trình duyệt cũ

// 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));
}

Tái bút: nếu bạn chỉ sử dụng một số không đổi với số 0 ở đầu (thay vì một chuỗi), nó vẫn được coi là cơ số 8 trong tất cả các trình duyệt hiện tại.
Agamemnus

0

Vấn đề dường như đã thay đổi trong hầu hết các trình duyệt.

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

=====

Đề nghị thực hành

Phải nói rằng, để an toàn hơn và tránh các vấn đề, hãy sử dụng tham số cơ số / cơ số như được đề xuất trong câu trả lời được chấp nhận .

parseInt("09", 10)    // 9

Kiểm tra thêm

Tôi chỉ muốn kiểm tra điều này, nếu đối số không phải là một chuỗi. Chrome & Safari cho kết quả chính xác. Firefox cũng trả về kết quả phù hợp, nhưng có cảnh báo.

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

Nếu giá trị bắt đầu bằng 0 và là một số, parseInt sẽ vẫn sử dụng cơ số 8. Hãy thử parseInt (020)
sirrocco

Đúng. Tôi thậm chí đã chỉ vào câu trả lời gợi ý. Và tôi biết các phương pháp hay nhất và các tính năng xấu cần tránh. Vì vậy, tôi cũng đã đưa ra phương pháp Đề xuất trong câu trả lời của mình.
mythicalcoder
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.