ไหนดีกว่าตัวเลข (x) หรือ parseFloat (x)


146

ไหนดีกว่ากัน

ฉันขอสิ่งนี้เพื่อการโกนสักสองสามไบต์เนื่องจากฉันสามารถใช้ + x แทน number (x) parsefloat ทำสิ่งที่ดีกว่านี้หรือไม่?


2
ตัวเลขทศนิยมที่มีความแม่นยำเดี่ยวใช้ 4 ไบต์ในระบบ 32 บิตเช่นเดียวกับจำนวนเต็มธรรมดา ฉันไม่รู้ว่าจาวาสคริปต์จัดการกับการลอยได้อย่างไร แต่ฉันคิดว่ามันเหมือนกันมาก
Christian

5
@Christian: ตัวเลขทั้งหมดใน Javascript เป็นทศนิยมความแม่นยำสองเท่า
Guffa

1
ฉันจะโหวตให้กับคำถามนี้ถ้ามันไม่ได้สำหรับส่วนแก้ไข
LaPuyaLoca

คำตอบ:


309

ความแตกต่างระหว่าง parseFloat และ Number

parseFloat/ ใช้parseIntสำหรับการวิเคราะห์สตริงในขณะที่Number/ ใช้+สำหรับการบังคับค่าให้กับตัวเลข พวกเขาทำงานแตกต่างกัน แต่ก่อนอื่นเรามาดูว่าพวกเขาประพฤติตนอย่างไร:

parseFloat('3'); // => 3
Number('3'); // => 3
parseFloat('1.501'); // => 1.501
Number('1.501'); // => 1.501
parseFloat('1e10'); // => 10000000000
Number('1e10'); // => 10000000000

ดังนั้นตราบใดที่คุณมีอินพุตตัวเลขมาตรฐานไม่มีความแตกต่าง อย่างไรก็ตามหากการป้อนข้อมูลของคุณเริ่มต้นด้วยตัวเลขแล้วมีอักขระอื่น ๆ ให้parseFloatตัดทอนตัวเลขออกจากสตริงในขณะที่Numberให้NaN(ไม่ใช่ตัวเลข):

parseFloat('1x'); // => 1
Number('1x'); // => NaN

นอกจากนี้Numberเข้าใจอินพุตฐานสิบหกขณะที่parseFloatไม่:

parseFloat('0x10'); // => 0
Number('0x10'); // => 16

แต่Numberทำตัวประหลาดกับสตริงว่างหรือสตริงที่มีพื้นที่สีขาวเท่านั้น:

parseFloat(''); // => NaN
Number(''); // => 0
parseFloat(' \r\n\t'); // => NaN
Number(' \r\n\t'); // => 0

โดยรวมแล้วฉันคิดว่าNumberมีเหตุผลมากกว่าดังนั้นฉันจึงมักจะใช้Numberเป็นการส่วนตัว (และคุณจะพบว่ามีการใช้งานจาวาสคริปต์ภายในจำนวนมากNumberเช่นกัน) ถ้าคนประเภทฉันชอบที่จะแสดงให้เห็นข้อผิดพลาดมากกว่าการรักษามันราวกับว่าพวกเขาได้พิมพ์'1x' '1'ครั้งเดียวที่ฉันทำข้อยกเว้นจริงๆคือเมื่อฉันแปลงสไตล์เป็นตัวเลขซึ่งในกรณีนี้parseFloatมีประโยชน์เพราะสไตล์มีรูปแบบเช่น'3px'ในกรณีที่ฉันต้องการวาง'px'ส่วนและเพิ่งได้รับ3ดังนั้นฉันจึงพบว่ามีparseFloatประโยชน์ ที่นี่ แต่จริงๆแล้วรูปแบบใดที่คุณเลือกนั้นขึ้นอยู่กับคุณและรูปแบบของข้อมูลที่คุณต้องการยอมรับ

โปรดทราบว่าการใช้ตัวดำเนิน+การunary นั้นเหมือนกับการใช้Numberฟังก์ชั่น:

Number('0x10'); // => 16
+'0x10'; // => 16
Number('10x'); // => NaN
+'10x'; // => NaN
Number('40'); // => 40
+'40'; // => 40

ดังนั้นฉันมักจะใช้+สั้น ๆ ตราบใดที่คุณรู้ว่ามันทำอะไรฉันก็อ่านง่าย


2
ฉันจะไม่พิจารณาwhitespace => 0พฤติกรรมของNumber()ในฐานะ "แปลก" ฉันจะพิจารณาว่ามันเป็นไปตามที่คาดหวังมากกว่า whitespace เป็นค่าว่าง แต่มันไม่ใช่ null / undefined => 0 เป็นผลลัพธ์ที่ดี ยิ่งใหญ่ (+) สำหรับคุณเพื่อนำเสนอต่อไป :) :)
jave.web

4
@NathanWall: อาจต้องการที่จะพูดถึงว่าNumber('Infinity') === Infinityในขณะที่parseInt('Infinity') === NaN
sstur

3
ฉันจะไม่ใช้+(unary plus) สำหรับสิ่งนี้เพราะถ้าคุณลืมเครื่องหมายอัฒภาคในบรรทัดก่อนหน้านิพจน์การบวกอาจถูกประเมินแทน
แจ็กสัน

1
สำหรับกรณีที่พวกเขาทำงานเหมือนกันฉันได้พบว่า parseFloat นั้นช้าลงจาก 1% ถึง 15% กลายเป็นช้าลงเมื่อจำนวนตัวเลขทศนิยมในสตริงเพิ่มขึ้น ด้วยการรัน 1M ในระบบของฉัน parseFloat ('1.501') นั้นช้ากว่า Number ('1.501') 5% และ parseFloat ('1.50137585467') นั้นช้ากว่า Number ('1.50137585467') 15% ดังนั้นฉันไปหา Number ()
bytepan

1
@ ChrisBrownie55 ว้าวจับได้ดี ฉันไม่รู้ว่าการแยกวิเคราะห์ลอยสามารถทำเช่นนั้นได้ ฉันเดาว่าอินฟินิตี้ไม่ใช่จำนวนเต็ม!
sstur

9

ความแตกต่างคือสิ่งที่เกิดขึ้นเมื่ออินพุตไม่ใช่ "หมายเลขที่เหมาะสม" Numberส่งคืนNaNขณะที่parseFloatวิเคราะห์คำว่า "มากที่สุด" หากเรียกร้องสตริงว่างNumberผลตอบแทนในขณะที่ผลตอบแทน0 parseFloatNaN

ตัวอย่างเช่น:

Number("") === 0               // also holds for false
isNaN(parseFloat("")) === true // and null

isNaN(Number("32f")) === true
parseFloat("32f") === 32

4
โปรดทราบว่าNaN != NaNแม้ว่า
WEX

@ ยอดเยี่ยมโอ้คุณพูดถึงว่าNaN != NaNประเมินเป็นTRUE - ขอบคุณสำหรับเคล็ดลับ!
jave.web

4
ใช้isNaN ()เพื่อทดสอบค่า NaN, isNaN(NaN)คืนtrue
jave.web

5

ในตัวอย่างเหล่านี้คุณสามารถเห็นความแตกต่าง:

Number('') = 0;
Number(false) = 0;
Number('1a') = NaN;

parseFloat('') = NaN;
parseFloat(false) = NaN;
parseFloat('1a') = 1;

parseFloat ช้าลงเล็กน้อยเนื่องจากค้นหาการปรากฏตัวครั้งแรกของตัวเลขในสตริงในขณะที่ Number constuctor สร้างอินสแตนซ์จำนวนใหม่จากสตริงที่มีค่าตัวเลขที่มีช่องว่างหรือที่มีค่าเท็จ

ป.ล. หากคุณสนใจโซลูชันการแปลงประเภทสากลคุณสามารถอ่านโพสต์เกี่ยวกับการแปลงประเภทในบล็อกของฉัน: http://justsimplejs.blogspot.com/2012/08/data-type-conversion.html


2

สำหรับสตริงว่างพวกเขาจะแตกต่างกัน

+""และNumber("")ส่งคืน 0 ขณะที่parseFloat("")ส่งคืน NaN


2
ฉันจะไปไกลเท่าที่จะบอกว่าparseFloat()มีผลถูกต้องเป็นสตริงว่างเปล่าไม่ใช่ตัวเลข0(อ่าน: NaN) ในขณะที่สตริงที่มีตัวละคร"0"อยู่ในนั้นคือ0;
Christopher

+xส่งคืน0ไม่เพียง แต่สำหรับสตริงว่าง แต่ยังสำหรับสตริงช่องว่างเท่านั้น ตัวอย่าง: +" ", +"\t\t\t", +"\n\n"- ทั้งหมดของพวกเขาให้0เป็นผล
Lukasz Wiktor

2

เท่าที่ฉันรู้และนี่เป็นเพียงการได้ยินจากเพื่อนร่วมงานดังนั้นอาจได้รับการแจ้งว่าป่วยโดยสิ้นเชิง parseFloat นั้นเร็วกว่าเล็กน้อย

แม้ว่าจะทำการค้นคว้าเพิ่มเติมต่อไปดูเหมือนว่าความแตกต่างด้านประสิทธิภาพนี้ขึ้นอยู่กับเบราว์เซอร์

http://jsperf.com/parseint-vs-parsefloat/6

ดูผล jsPerf เหล่านี้และโทรหาคุณ (มันรวมการทดสอบ + x ด้วย)

ตามที่ระบุไว้ในคำตอบของ @xdazz +""และNumber("")กลับมา0ในขณะที่parseFloat("")ส่งกลับNaNอีกครั้งฉันจะไปกับ parseFloat เพราะสตริงว่างไม่ได้หมายความว่าหมายเลข 0 เพียงสตริงที่มีอักขระ"0"ในนั้นหมายถึง 0;


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