Cái nào tốt hơn, số (x) hay parseFloat (x)?


146

Cái nào tốt hơn?

Tôi đang hỏi điều này chỉ vì mục đích cạo một vài byte, vì tôi có thể sử dụng + x thay vì số (x). Parsefloat có làm gì tốt hơn không?


2
Các số dấu phẩy động chính xác đơn chiếm 4 byte trong hệ thống 32 bit cũng như các số nguyên đơn giản. Tôi không biết làm thế nào javascript xử lý nổi, nhưng tôi đoán nó khá giống nhau.
Christian

5
@Christian: Tất cả các số trong Javascript là số float chính xác kép.
Guffa

1
Tôi sẽ bỏ phiếu cho UP cho câu hỏi này nếu nó không dành cho phân khúc EDIT
LaPuyaLoca

Câu trả lời:


309

Sự khác biệt giữa parseFloat và Number

parseFloat/ parseIntlà để phân tích một chuỗi, trong khi Number/ +là để ép buộc một giá trị thành một số. Họ cư xử khác nhau. Nhưng trước tiên hãy nhìn vào nơi họ cư xử giống nhau:

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

Vì vậy, miễn là bạn có đầu vào số tiêu chuẩn, không có sự khác biệt. Tuy nhiên, nếu đầu vào của bạn bắt đầu bằng một số và sau đó chứa các ký tự khác, hãy parseFloatcắt số đó ra khỏi chuỗi, trong khi Numberđưa ra NaN(không phải là một số):

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

Ngoài ra, Numberhiểu đầu vào thập lục phân trong khi parseFloatkhông:

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

Nhưng Numberhành động kỳ lạ với chuỗi trống hoặc chuỗi chỉ chứa khoảng trắng:

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

Nhìn chung, tôi thấy Numberhợp lý hơn, vì vậy tôi hầu như luôn sử dụng Numbercá nhân (và bạn sẽ thấy rằng rất nhiều hàm JavaScript nội bộ Numbercũng sử dụng ). Nếu ai đó loại '1x'tôi thích hiển thị một lỗi hơn là xử lý như thể họ đã gõ '1'. Lần duy nhất tôi thực sự tạo ra một ngoại lệ là khi tôi chuyển đổi một kiểu thành một số, trong trường hợp đó parseFloatlà hữu ích vì các kiểu có dạng như '3px', trong trường hợp đó tôi muốn bỏ 'px'phần đó và chỉ lấy 3, vì vậy tôi thấy parseFloathữu ích đây. Nhưng thực sự cái nào bạn chọn là tùy thuộc vào bạn và hình thức đầu vào nào bạn muốn chấp nhận.

Lưu ý rằng việc sử dụng toán tử đơn nguyên +giống hệt như sử dụng Numbernhư một hàm:

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

Vì vậy, tôi thường chỉ sử dụng +cho ngắn. Miễn là bạn biết nó làm gì, tôi thấy nó dễ đọc.


2
Tôi sẽ không coi khoảng trắng => 0 hành vi Number()là "lạ" Tôi thậm chí sẽ coi nó như mong đợi hơn, khoảng trắng là một giá trị trống nhưng nó không phải là null / không xác định => 0 là một kết quả tốt. Lớn (+) cho bạn cho các showcase nào :)
jave.web

4
@NathanWall: Có thể muốn đề cập đến điều đó Number('Infinity') === Infinitytrong khiparseInt('Infinity') === NaN
sstur

3
Tôi sẽ không sử dụng +(unary plus) cho điều này, bởi vì nếu bạn quên dấu chấm phẩy trên dòng trước đó, một biểu thức bổ sung có thể được đánh giá thay thế.
Jackson

1
Đối với các trường hợp họ hành xử giống như tôi đã phát hiện ra rằng parseFloat chậm hơn từ 1% đến 15%, trở nên chậm hơn khi số chữ số thập phân trong chuỗi tăng lên. Với 1M chạy trong hệ thống của tôi, parseFloat ('1.501') chậm hơn 5% so với Số ('1.501') và parseFloat ('1.50137585467') chậm hơn 15% so với Số ('1.50137585467'). Vì vậy, tôi đi cho Số ().
bytepan

1
@ ChrisBrownie55 Wow, bắt tốt. Tôi không biết parseFloat có thể làm điều đó. Tôi đoán Infinity không phải là số nguyên!
sstur

9

Sự khác biệt là những gì xảy ra khi đầu vào không phải là "số thích hợp". Numbertrả về NaNtrong khi parseFloatphân tích cú pháp "càng nhiều càng tốt". Nếu được gọi trên chuỗi rỗng Numbertrả về 0trong khi parseFloat trả về NaN.

Ví dụ:

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

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

4
Lưu ý rằng NaN != NaNmặc dù
Wex

@Wex Oh bạn nghĩ rằng NaN != NaNđánh giá thành TRUE - cảm ơn vì tiền boa!
jave.web

4
sử dụng isNaN () để kiểm tra giá trị NaN, isNaN(NaN)trả vềtrue
jave.web

5

Trong những ví dụ này, bạn có thể thấy sự khác biệt:

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

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

parseFloat chậm hơn một chút vì nó tìm kiếm sự xuất hiện đầu tiên của một số trong một chuỗi, trong khi đó, bộ tạo Số tạo ra một thể hiện số mới từ các chuỗi chứa các giá trị số có khoảng trắng hoặc chứa các giá trị sai.

PS Nếu bạn quan tâm đến một số giải pháp chuyển đổi loại phổ quát, bạn có thể đọc bài đăng về chuyển đổi loại trong blog của tôi: http://jowersimplejs.blogspot.com/2012/08/data-type-conversion.html


2

Đối với chuỗi rỗng, chúng là khác nhau.

+""Number("")trả về 0, trong khi parseFloat("")trả về NaN.


2
Tôi sẽ đi xa hơn để nói rằng parseFloat()có kết quả đúng vì một chuỗi rỗng KHÔNG phải là số 0(đọc: NaN) trong khi một chuỗi có ký tự "0"trong đó là IS 0;
Christopher

+xtrả về 0không chỉ cho một chuỗi trống mà còn cho bất kỳ chuỗi chỉ có khoảng trắng. Ví dụ: +" ", +"\t\t\t", +"\n\n"- tất cả trong số họ cung cấp cho 0kết quả
Lukasz Wiktor

2

Theo như tôi biết, và điều này chỉ được nghe lén từ các đồng nghiệp nên có thể hoàn toàn không được thông báo, rằng parseFloat nhanh hơn một chút.

Mặc dù nghiên cứu sâu hơn, có vẻ như sự khác biệt hiệu suất này phụ thuộc vào trình duyệt.

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

Hãy xem các kết quả jsPerf này và thực hiện cuộc gọi của bạn. (bao gồm cả các bài kiểm tra + x)

Như đã lưu ý trong câu trả lời của @xdazz +""Number("")trả về 0trong khi parseFloat("")trả về NaNnên một lần nữa tôi sẽ đi với parseFloat, bởi vì một chuỗi rỗng KHÔNG có nghĩa là số 0, chỉ một chuỗi có ký tự "0"trong đó có nghĩa là 0;


Đây là một thử nghiệm toàn diện hơn để tìm cách chuyển đổi nhanh hơn ... parseFloat()vẫn là người chiến thắng.
mindplay.dk
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.