Javascript parseInt () ที่มีศูนย์นำหน้า


121

ฟังก์ชัน parseInt ของ Javascript ดูเหมือนจะไม่ทำงานอย่างสมบูรณ์

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

คุณไม่สามารถอธิบายเรื่องนั้นได้ ให้มันลอง. (jsFiddle)

แก้ไขเนื่องจากมีการถามและตอบคำถามนี้ "คุณลักษณะ" ของการตั้งค่าเริ่มต้นเป็นเลขฐานแปดจึงเลิกใช้งานแล้ว [ 1 ] [ 2 ]


30
คุณต้องล้อเล่น
georg

6
You can't explain that. ใช่คุณสามารถ => developer.mozilla.org/en/JavaScript/Reference/Global_Objects/…
Rocket Hazmat

3
ตั้งแต่อายุมากขึ้นตัวเลขใด ๆ ที่ขึ้นต้นด้วย 0 หมายถึง OCTAL และ 0x หมายถึง Hexa-Decimal ฉันเชื่อว่านี่เป็นสากลสำหรับทุกภาษา แต่อีกครั้งฉันอาจจะคิดผิด
Selvakumar Arumugam

3
FYI: jsFiddleเป็นเครื่องทดสอบ JavaScript ออนไลน์ดีกว่าw3schools.com/jsref/tryit.asp
Rocket Hazmat

2
@JohnHartsock ใช่เป็นเพราะเราทั้งคู่อยู่ในโพสต์นี้stackoverflow.com/questions/8761997/…
savinger

คำตอบ:


183

เนื่องจากถ้าตัวเลขขึ้นต้นด้วย '0' จะถือว่าเป็นฐาน 8 (ฐานแปด)

คุณสามารถบังคับฐานโดยส่งฐานเป็นพารามิเตอร์ที่ 2

parseInt("09", 10) // 9

ตามเอกสารพารามิเตอร์ที่ 2 เป็นทางเลือก แต่ไม่ได้ถือว่าเป็น 10 เสมอไปดังที่คุณเห็นจากตัวอย่างของคุณ


1
ใช่ แต่ถ้าสมมติว่าเป็นเลขฐานแปดมันควรจะส่งกลับ 11 สำหรับ 09 แทนที่จะเป็น 0
Peeyush Kushwaha

2
@PeeyushKushwaha: วิธีอื่น ๆ 11ในฐาน 8 อยู่9ในฐาน 10 09ไม่ใช่เลขฐาน 8 ที่ถูกต้อง
Rocket Hazmat

แต่ฉันต้องการ 09 หลังจาก parseInt มีวิธีใดบ้าง
Pardeep Jain

39

การเรียกถึงparseIntควรระบุฐานในอาร์กิวเมนต์ที่สองเสมอ:

parseInt("08", 10);

รุ่นก่อนหน้านี้ของ JavaScript สตริงรักษาเริ่มต้นด้วยการ0เป็นฐานแปด (เมื่อฐานไม่ได้ระบุ) และค่า08มิได้09เป็นตัวเลขฐานแปดที่ถูกต้อง

จากเอกสาร Mozilla :

หากไม่ได้กำหนด radix หรือ 0 JavaScript จะถือว่าสิ่งต่อไปนี้:

  • หากสตริงอินพุตขึ้นต้นด้วย "0x" หรือ "0X" เลขฐานสิบหกคือ 16 (เลขฐานสิบหก)
  • หากสตริงอินพุตขึ้นต้นด้วย "0" เลขฐานแปด (ฐานแปด) คุณลักษณะนี้ไม่เป็นไปตามมาตรฐานและการใช้งานบางอย่างจงใจไม่สนับสนุนคุณลักษณะนี้ (ใช้รัศมี 10 แทน) ด้วยเหตุนี้มักจะระบุ Radix เมื่อใช้ parseInt
  • หากสตริงอินพุตเริ่มต้นด้วยค่าอื่น ๆ รัศมีคือ 10 (ทศนิยม)

ถ้าไม่สามารถแปลงอักขระตัวแรกเป็นตัวเลขได้ parseInt จะส่งกลับ NaN

และจากมาตรฐานECMAScript 3 :

เมื่อรัศมีเป็น 0 หรือไม่ได้กำหนดและหมายเลขของสตริงเริ่มต้นด้วย0 หลักไม่ตามด้วยxหรือXดังนั้นการใช้งานอาจตีความตัวเลขว่าเป็นเลขฐานแปดหรือทศนิยมตามดุลยพินิจของตน แนะนำให้ใช้งานเพื่อตีความตัวเลขในกรณีนี้ว่าเป็นทศนิยม

JavaScript เวอร์ชันล่าสุด ( ECMAScript 5 ) จะละทิ้งพฤติกรรมนี้แต่คุณยังควรระบุ radixเพื่อตอบสนองเบราว์เซอร์รุ่นเก่า


เนื่องจากสิ่งนี้เลิกใช้แล้วในอนาคตคุณจะสามารถใช้เลขศูนย์นำหน้าได้ใช่หรือไม่?
Pacerier

15

มีพารามิเตอร์ Radix

parseInt(value, base)

ฐานอยู่ที่ไหน

ในกรณีนี้คุณกำลังประเมินตัวเลข base10 (ทศนิยม) ดังนั้นให้ใช้

parseInt(value, 10);

4

ดูเหมือนจะไม่ถูกต้องอย่างสมบูรณ์ในเบราว์เซอร์ใหม่ Internet Explorer 9 และ 10 จะส่งคืน 8 หากคุณเรียกใช้ 'parseInt ("08")' ในขณะที่ Internet Explorer 8 และเวอร์ชันก่อนหน้าจะคืนค่าเป็น 0 (IE10 ในโหมด quirks จะส่งกลับ 0 ด้วย)

Chrome เวอร์ชันล่าสุดยังส่งคืน 8 ดังนั้นจึงต้องเปลี่ยนการตีความเมื่อเร็ว ๆ นี้


ใช่พฤติกรรมเปลี่ยนไปแล้ว ฉันจะอัปเดตคำตอบของฉัน developer.mozilla.org/en-US/docs/JavaScript/Reference/…
Wayne

1
ใช่ Firefox และ Chrome เวอร์ชันล่าสุดไม่มีปัญหาในตอนนี้
mythicalcoder

3

ปัญหานี้เลิกใช้แล้ว แต่คุณยังสามารถใช้ radix parseIntเพื่อแปลงจำนวนฐานอื่น ๆ ให้เป็นฐาน -10 ได้ เช่น,

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

ผลตอบแทน17(ซึ่งเป็นฐาน -10 ของ0010001)


0

เคล็ดลับ: อย่างที่คุณทราบเมื่อเลิกใช้ค่าเริ่มต้นเป็นฐานแปดแล้ว นี่คือวิธีแก้ไขในเบราว์เซอร์เดิม

// 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: ถ้าคุณใช้เพียงตัวเลขคงที่โดยมีศูนย์นำหน้า (แทนที่จะเป็นสตริง) จะถือว่าเป็นเลขฐาน 8 ในเบราว์เซอร์ปัจจุบันทั้งหมด
Agamemnus

0

ดูเหมือนว่าปัญหาจะเปลี่ยนไปแล้วในเบราว์เซอร์ส่วนใหญ่

Firefox 51.0.1 (64 บิต)

parseInt("09")   // 9

Chrome 55.0.2883.95 (64 บิต)

parseInt("09")   // 9

Safari 10.0 (12602.1.50.0.10)

parseInt("09")   // 9

=====

แนวทางปฏิบัติที่แนะนำ

ต้องบอกว่าเพียงเพื่อจะอยู่ในด้านความปลอดภัยและเพื่อหลีกเลี่ยงปัญหาการใช้พารามิเตอร์ฐาน / สมุฎฐานตามที่แนะนำในคำตอบที่ได้รับการยอมรับ

parseInt("09", 10)    // 9

การทดสอบพิเศษ

ฉันแค่อยากจะทดสอบสิ่งนี้เช่นกันถ้าอาร์กิวเมนต์ไม่ใช่สตริง Chrome & Safari ให้ผลลัพธ์ที่แน่นอน Firefox ก็ให้ผลลัพธ์ที่เหมาะสมเช่นกัน แต่มีคำเตือน

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

ถ้าค่าเริ่มต้นด้วย 0 และเป็นตัวเลข parseInt จะยังคงใช้ฐาน 8 ลอง parseInt (020)
sirrocco

ใช่. ฉันได้ชี้ไปที่คำตอบที่แนะนำแล้ว และฉันรู้แนวทางปฏิบัติที่ดีที่สุดและคุณลักษณะที่ไม่ดีที่ควรหลีกเลี่ยง ดังนั้นฉันจึงได้ให้แนวทางปฏิบัติที่แนะนำเช่นกันในคำตอบของฉัน
mythicalcoder
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.