ความแตกต่างระหว่าง parseInt () และ Number () คืออะไร?


คำตอบ:


457

ดีที่พวกเขามีความแตกต่างกันความหมายที่Numberคอนสตรัคเรียกว่าเป็นฟังก์ชั่นการดำเนินการแปลงชนิดและparseIntดำเนินการแยกเช่น:

// parsing:
parseInt("20px");       // 20
parseInt("10100", 2);   // 20
parseInt("2e1");        // 2

// type conversion
Number("20px");       // NaN
Number("2e1");        // 20, exponential notation

โปรดทราบว่าหากparseIntตรวจพบศูนย์นำบนสตริงมันจะแยกตัวเลขในฐานแปดซึ่งมีการเปลี่ยนแปลงใน ECMAScript 5 ซึ่งเป็นรุ่นใหม่ของมาตรฐาน แต่จะใช้เวลานานในการใช้เบราว์เซอร์ ความไม่ลงรอยกันกับ ECMAScript 3) นอกจากนี้ยังparseIntจะละเว้นอักขระต่อท้ายที่ไม่สอดคล้องกับตัวเลขใด ๆ ของฐานที่ใช้ในปัจจุบัน

คอนNumberสตรัคไม่ตรวจจับ octals:

Number("010");         // 10
parseInt("010");       // 8, implicit octal
parseInt("010", 10);   // 10, decimal radix used

แต่สามารถจัดการตัวเลขในรูปแบบเลขฐานสิบหกได้เช่นparseInt:

Number("0xF");   // 15
parseInt("0xF"); //15

นอกจากนี้โครงสร้างที่ใช้กันอย่างแพร่หลายเพื่อทำการแปลงชนิดตัวเลขคือUnary +Operator (หน้า 72)ซึ่งเทียบเท่ากับการใช้ตัวNumberสร้างเป็นฟังก์ชัน:

+"2e1";   // 20
+"0xF";   // 15
+"010";   // 10

ที่น่าสนใจไม่แยกวิเคราะห์อักขระใด ๆ ที่ตามหลังตัวเลขหรือไม่ เพราะในกรณีของฉันฉันต้องการรับ NaN แทนที่จะเป็น 20 เมื่อแปลง
ทำเครื่องหมาย

ใช่แล้ว. ดูเหมือนคุณต้องการ Number ()
Gareth

ตกลงดังนั้นฉันเดาว่าฉันจะไปกับ Number () แต่ขอบคุณมากสำหรับการเคลียร์ประเด็นนี้และตัวอย่างทั้งหมด! :-)
ทำเครื่องหมาย

1
ขอบคุณสำหรับสิ่งนี้. นี่เป็นครั้งแรกที่ฉันเห็น NaN มันอาจจะมีประโยชน์สำหรับบางคนที่จะรู้ว่า NaN ทดสอบด้วยฟังก์ชั่น isNaN (ค่า) เพียงแค่ใช้ "if (value == NaN)" ตัวอย่างเช่นจะไม่ทำงาน
WonderfulDay

1
Number()ไม่จัดการกับ octals เหมือนฐานสิบหกและไบนารี:Number('0o10') == 8
ฆ Mendes

22
typeof parseInt("123") => number
typeof Number("123") => number
typeof new Number("123") => object (Number primitive wrapper object)

สองรายการแรกจะให้ประสิทธิภาพที่ดีขึ้นเนื่องจากส่งคืนค่าดั้งเดิมแทนวัตถุ


20
new Number() แตกต่างจาก Number()จาก typeof Number("123") => number
Gareth

8
new Number("1") != new Number("1")ด้วย ไม่เคยใช้ new Numberไม่เคยไม่เคยไม่เคยไม่เคย Number("1")ในทางกลับกันมีเหตุผลอย่างสมบูรณ์แบบ
Kragen Javier Sitaker

18
@Kragen มันจะมีประโยชน์มากขึ้นกับชุมชนถ้าคุณอธิบายว่าทำไมคุณไม่ควรใช้ "หมายเลขใหม่" - แทนที่จะพิมพ์ "ไม่เคย" 5 ครั้ง ...
ken

1
@ken ความคิดเห็นเก่าแก่มาก แต่สำหรับผู้เยี่ยมชมในอนาคตฉันคิดว่ามันเป็นเพราะเหตุผลที่พวกเขากล่าวถึงเริ่มต้นด้วย ฉันแยกวิเคราะห์ตัวเลขสองตัวlet x = new Number("2"); let y = new Number("2");จากนั้นจึงทำการตรวจสอบความเท่าเทียมกันไม่ว่าด้วยเหตุผลใดก็ตามควรจะเรียกว่าif (x == y) { doSomething(); }มีเหตุผล doSomethingแต่มันจะไม่ นอกจากนี้หากคุณต้องวิเคราะห์ตัวเลขเพียงหนึ่งหมายเลขlet x = new Number("2");ก็x === 2จะเป็นเท็จ นั่นเป็นเหตุผลที่ชัดเจนว่าทำไมคุณไม่ควรใช้new Number
Tom C

1
@TomC คุณเห็นผลลัพธ์ของความคิดเห็นที่แก้ไขแล้ว (นั่นคือสิ่งที่ไอคอนดินสอตามความคิดเห็น) ก่อนหน้านี้มีคำอธิบายที่เป็นศูนย์เพียงคำตักเตือนที่แข็งแกร่ง
เคน

15

หากคุณกำลังมองหาประสิทธิภาพแล้วผลลัพธ์ที่ดีที่สุดอาจเป็นไปได้ว่าคุณจะได้รับการเปลี่ยนระดับบิตตามค่า"10">>0เล็กน้อย คูณด้วย ( "10" * 1) หรือไม่ ( ~~"10") ทั้งหมดนั้นเร็วกว่าNumberและparseIntมาก พวกเขายังมี "คุณสมบัติ" กลับ 0 เนื่องจากไม่มีการโต้แย้งตัวเลข นี่คือการทดสอบประสิทธิภาพ


1
ความเร็วของวิธีการต่างๆนั้นเปลี่ยนแปลงไปตามการแก้ไขของเบราว์เซอร์เมื่อเวลาผ่านไป การทดสอบที่เชื่อมโยงมีการเปลี่ยนแปลงและเวอร์ชันล่าสุดตามความคิดเห็นนี้อยู่ที่นี่ - jsperf.com/number-vs-parseint-vs-plus/39 - โชคดีที่เว็บไซต์มีการทดสอบรุ่นก่อนหน้าด้วย
bobo

@bobo แน่นอน ตรวจสอบจากความอยากรู้ด้วยโครเมี่ยม - NumberและparseIntยังช้ากว่า 99% ที่เหลือ นอกจากนี้สำหรับฉันแล้วพวกเขาก็มีเสน่ห์ดึงดูดสายตาน้อยลงเช่นกัน :-)
Saulius

15
ต้องการความชัดเจนของรหัสมากกว่าการเพิ่มประสิทธิภาพ "ไร้ประโยชน์" เสมอ สำหรับกรณีการใช้งานส่วนใหญ่parseIntหรือNumberเป็นที่นิยมมากกว่า หากคุณกำลังเขียนโปรแกรมจำลอง N64 ด้วยการแปลงหลายล้านต่อวินาทีคุณอาจพิจารณาเทคนิคเหล่านั้น
ngryman

1
คำถามเกี่ยวกับพฤติกรรมการอภิปรายเกี่ยวกับประสิทธิภาพเป็นหัวข้อ
นิวเมติกส์

1
โปรดทราบว่าสิ่งนี้ไม่สามารถใช้กับจำนวนเต็มขนาดใหญ่โดยเฉพาะจำนวนเต็มที่ไม่พอดีกับจำนวนเต็มแบบ 32 บิตที่เซ็นชื่อเนื่องจากใน JavaScript ตัวดำเนินการระดับบิตจะถือว่าตัวถูกดำเนินการเป็นลำดับ 32 บิตแทนที่จะเป็นทศนิยม เลขฐานสิบหกหรือเลขฐานแปด ดังนั้นจะล้นไป(2**31).toString() >> 0 -2147483648คุณสามารถใช้>>>แทน>>ให้ JavaScript ปฏิบัติต่อตัวถูกดำเนินการเป็นจำนวนเต็ม 32 บิตที่ไม่ได้ลงนามแต่จากนั้นตัวเลขใด ๆ ที่ใหญ่กว่า2**32 - 1จะล้น
hasc


6

หนึ่งความแตกต่างเล็ก ๆ น้อย ๆ เป็นสิ่งที่พวกเขาแปลงของundefinedหรือnull,

Number() Or Number(null) // returns 0

ในขณะที่

parseInt() Or parseInt(null) // returns NaN

6

สรุป:

parseInt():

  • รับสตริงเป็นอาร์กิวเมนต์แรกคือ radix (จำนวนเต็มซึ่งเป็นฐานของระบบตัวเลขเช่นทศนิยม 10 หรือไบนารี 2) เป็นอาร์กิวเมนต์ที่สอง
  • ฟังก์ชันจะคืนค่าตัวเลขจำนวนเต็มหากอักขระตัวแรกไม่สามารถแปลงเป็นตัวเลขได้NaNจะถูกส่งคืน
  • หากparseInt()ฟังก์ชันพบค่าที่ไม่ใช่ตัวเลขฟังก์ชันจะตัดส่วนที่เหลือของสตริงป้อนเข้าออกและแยกวิเคราะห์เฉพาะส่วนจนกระทั่งค่าที่ไม่ใช่ตัวเลข
  • หาก radix เป็นundefinedหรือ 0 JS จะถือว่าสิ่งต่อไปนี้:
    • หากสตริงอินพุตเริ่มต้นด้วย "0x" หรือ "0X" radix คือ 16 (เลขฐานสิบหก) ส่วนที่เหลือของสตริงจะถูกวิเคราะห์เป็นตัวเลข
    • หากค่าอินพุตเริ่มต้นด้วย 0 radix สามารถเป็น 8 (ฐานแปด) หรือ 10 (ฐานสิบ) Radix ที่เลือกขึ้นอยู่กับการนำไปใช้งานของโปรแกรม JS ES5ระบุว่า 10 ควรใช้แล้ว อย่างไรก็ตามเบราว์เซอร์ทั้งหมดนี้ไม่รองรับดังนั้นจึงควรระบุ radix เสมอหากหมายเลขของคุณสามารถขึ้นต้นด้วย 0
    • หากค่าอินพุตเริ่มต้นด้วยตัวเลขใด ๆ Radix จะเป็น 10

Number():

  • ตัวNumber()สร้างสามารถแปลงอินพุตอาร์กิวเมนต์ใด ๆ ให้เป็นตัวเลข หากตัวNumber()สร้างไม่สามารถแปลงอินพุตเป็นตัวเลขNaNจะถูกส่งคืน
  • คอนสตรัคยังสามารถจัดการกับเลขฐานสิบหกพวกเขาจะต้องเริ่มต้นด้วยNumber()0x

ตัวอย่าง:

console.log(parseInt('0xF', 16));  // 15

// z is no number, it will only evaluate 0xF, therefore 15 is logged
console.log(parseInt('0xFz123', 16));

// because the radix is 10, A is considered a letter not a number (like in Hexadecimal)
// Therefore, A will be cut off the string and 10 is logged
console.log(parseInt('10A', 10));  // 10

// first character isnot a number, therefore parseInt will return NaN
console.log(parseInt('a1213', 10));


console.log('\n');


// start with 0X, therefore Number will interpret it as a hexadecimal value
console.log(Number('0x11'));

// Cannot be converted to a number, NaN will be returned, notice that
// the number constructor will not cut off a non number part like parseInt does
console.log(Number('123A'));

// scientific notation is allowed
console.log(Number('152e-1'));  // 15.21


5

ฉันใช้ parseInt เสมอ แต่ระวังเลขศูนย์นำหน้าที่จะบังคับให้เข้าสู่โหมดเลขฐานแปด


35
ฉันคิดว่ามันเป็นความคิดที่ดีในการจัดหา Radix ให้parseInt(value, radix)วิธีการที่คุณไม่ได้มีอุบัติเหตุฐานแปดโหมดการแปลง ฯลฯ
awesomo

เลขศูนย์นำหน้าจะบังคับให้เข้าสู่โหมดเลขฐานแปดใน ECMAScript 3 ECMAScript 5 จะแยกวิเคราะห์0แม้ในโหมดที่ไม่เข้มงวด แต่ตอนนี้ได้รับการแก้ไขและศูนย์ชั้นนำในขณะนี้จะถูกละเว้นเพียงเพื่อที่จะกลายเป็นparseInt("070") 70
Piotrek Hryciuk

2
คุณควรจะใช้ linter parseInt()เช่นกันที่จะเตือนคุณที่จะให้ค่ารากลง
Justin

2

parseInt() -> แยกวิเคราะห์ตัวเลขเพื่อ redix ที่ระบุ

Number()-> แปลงค่าที่ระบุให้เทียบเท่ากับตัวเลขหรือ NaN หากไม่สามารถทำเช่นนั้นได้

ดังนั้นสำหรับการแปลงค่าที่ไม่ใช่ตัวเลขให้เป็นตัวเลขเราควรใช้ฟังก์ชัน Number () เสมอ

เช่น.

Number("")//0
parseInt("")//NaN

Number("123")//123
parseInt("123")//123

Number("123ac") //NaN,as it is a non numeric string
parsInt("123ac") //123,it parse decimal number outof string

Number(true)//1
parseInt(true) //NaN

มีหลายมุมให้เลือก parseInt()เรือนทำงานเช่นเดียวกับการแปลง Redix ดังนั้นเราจึงควรหลีกเลี่ยงการใช้ฟังก์ชั่น parseInt () เพื่อวัตถุประสงค์ในการ coersion

ตอนนี้เพื่อตรวจสอบสภาพอากาศค่าที่ให้เป็นตัวเลขหรือไม่เราควรใช้isNaN()ฟังก์ชั่นพื้นเมือง


1

parseInt แปลงเป็นตัวเลขจำนวนเต็มนั่นคือมันจะตัดทศนิยม Number ไม่แปลงเป็นจำนวนเต็ม


1

มันเป็นความคิดที่ดีที่จะอยู่ห่างจาก parseInt และใช้ Number และ Math.round เว้นแต่ว่าคุณต้องการเลขฐานสิบหกหรือฐานแปด ทั้งสองสามารถใช้สตริง ทำไมต้องอยู่ห่างจากมัน

parseInt(0.001, 10)
0

parseInt(-0.0000000001, 10)
-1

parseInt(0.0000000001, 10)
1

parseInt(4000000000000000000000, 10)
4

มันสมบูรณ์ฆ่าเนื้อจำนวนมากหรือเล็กจริง ๆ มันผิดปกติพอทำงานได้ตามปกติถ้าอินพุตเหล่านี้เป็นสตริง

parseInt("-0.0000000001", 10)
0

parseInt("0.0000000001", 10)
0

parseInt("4000000000000000000000", 10)
4e+21

แทนที่จะเสี่ยงต่อการหาจุดบกพร่องด้วยสิ่งนี้และคนอื่น ๆ ที่กล่าวถึง gotchas ฉันจะหลีกเลี่ยงการแยกวิเคราะห์ยกเว้นว่าคุณจำเป็นต้องแยกวิเคราะห์สิ่งอื่นนอกเหนือจากฐาน 10 จำนวน, Math.round, Math.foor และ. toFixed (0) ทำสิ่งเดียวกันแยกวิเคราะห์สามารถใช้โดยไม่ต้องมีข้อผิดพลาดประเภทนี้

หากคุณต้องการหรือจำเป็นต้องใช้การแยกวิเคราะห์สำหรับคุณสมบัติอื่น ๆ ของมันอย่าใช้เพื่อแปลงการลอยตัวเป็น ints

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