Cách nhanh nhất để chuyển đổi Chuỗi thành Số trong JavaScript là gì?


122

Bất kỳ số nào, đó là số. Chuỗi trông giống như một số, đó là số. Mọi thứ khác, nó đi NaN.

'a' => NaN
'1' => 1
1 => 1

Điều gì là nhanh nhất phụ thuộc vào tối ưu hóa trong một triển khai nhất định tại một thời điểm nhất định. Không có cách nào khách quan là "nhanh nhất".
I Hate Lazy

2
Những gì nên được thực hiện với '1a'chuỗi? Với ' 1'một? Nói cách khác, tại sao hầu hết các phương pháp phổ biến để làm điều đó ( Number(x)parseInt(x, 10)) không đủ đối với bạn?
raina77ow

Một bài kiểm tra jsperf trước đó: jsperf.com/converting-string-to-int/3
epascarello

đây là một hiệu suất tốt so sánh các phương pháp khác nhau: jsben.ch/#/NnBKM
EscapeNetscape

Câu trả lời:


192

Có 4 cách để làm điều đó theo như tôi biết.

Number(x);
parseInt(x, 10);
parseFloat(x);
+x;

Bằng cách kiểm tra nhanh này mà tôi đã thực hiện, nó thực sự phụ thuộc vào các trình duyệt.

http://jsperf.com/best-of-string-to-number-conversion/2

Implicit được đánh dấu là nhanh nhất trên 3 trình duyệt, nhưng nó làm cho mã khó đọc… Vì vậy, hãy chọn bất cứ thứ gì bạn cảm thấy thích!


7
Điều thú vị là Google Analytics (phần bạn dán vào trang web của mình) sử dụng 1*để chuyển đổi từ ngày sang số, tương tự như +ở trên. tức là 1*new Date()hơn là +new Date(). Có thể nó dễ đọc hơn?
Matthew Wilcoxson

1
Tôi nghĩ 1*nó được ưa thích hơn vì nó ít bị lỗi hơn. Một biến treo lơ lửng không mong muốn trước đây +1không phải là lỗi phân tích cú pháp. Nó là một thủ thuật tương tự như sử dụng if (MYCONSTANT == myvar)trong C.
Tomas

5
@beatak - Các tối ưu hóa hiện tại dường như ưu tiên các phương pháp gốc hơn là chuyển đổi ngầm định. Tôi nhận được nhanh nhất cho Number () trong Chrome 37.0.2062.124 trên Windows Server 2008 R2 / 7 và ParseInt () trong Firefox 30.0 với mặc nhiên là chậm nhất cho cả hai. Ngoài ra, bạn có thể cân nhắc bao gồm chuỗi ký tự float trong thử nghiệm để so sánh chung. Dự đoán của tôi là nó có thể thay đổi thứ tự trong một số trường hợp vì chuyển đổi chuỗi thành float thường chậm hơn chuyển đổi chuỗi thành int. Cách kiểm tra hiện tại, nó sẽ biến mất với một chuỗi thành chuyển đổi int khi Number () được sử dụng.
Nolo

1
Chrome 61.0.3163. Số () là nhanh nhất.
Dmitry Petukhov

70

Có ít nhất 5 cách để làm điều này:

Nếu bạn chỉ muốn chuyển đổi thành số nguyên, một cách nhanh chóng (và ngắn gọn) khác là không bit theo chiều kép (tức là sử dụng hai ký tự dấu ngã):

ví dụ

~~x;

Tham khảo: http://james.padolsey.com/cool-stuff/double-bitwise-not/

5 cách phổ biến mà tôi biết cho đến nay để chuyển đổi một chuỗi thành một số đều có sự khác biệt (có nhiều toán tử bitwise hoạt động hơn, nhưng tất cả đều cho kết quả giống nhau ~~). JSFiddle này hiển thị các kết quả khác nhau mà bạn có thể mong đợi trong bảng điều khiển gỡ lỗi: http://jsfiddle.net/TrueBlueAussie/j7x0q0e3/22/

var values = ["123",
          undefined,
          "not a number",
          "123.45",
          "1234 error",
          "2147483648",
          "4999999999"
          ];

for (var i = 0; i < values.length; i++){
    var x = values[i];

    console.log(x);
    console.log(" Number(x) = " + Number(x));
    console.log(" parseInt(x, 10) = " + parseInt(x, 10));
    console.log(" parseFloat(x) = " + parseFloat(x));
    console.log(" +x = " + +x);
    console.log(" ~~x = " + ~~x);
}

Bảng điều khiển gỡ lỗi:

123
  Number(x) = 123
  parseInt(x, 10) = 123
  parseFloat(x) = 123
  +x = 123
  ~~x = 123
undefined
  Number(x) = NaN
  parseInt(x, 10) = NaN
  parseFloat(x) = NaN
  +x = NaN
  ~~x = 0
null
  Number(x) = 0
  parseInt(x, 10) = NaN
  parseFloat(x) = NaN
  +x = 0
  ~~x = 0
"not a number"
  Number(x) = NaN
  parseInt(x, 10) = NaN
  parseFloat(x) = NaN
  +x = NaN
  ~~x = 0
123.45
  Number(x) = 123.45
  parseInt(x, 10) = 123
  parseFloat(x) = 123.45
  +x = 123.45
  ~~x = 123
1234 error
  Number(x) = NaN
  parseInt(x, 10) = 1234
  parseFloat(x) = 1234
  +x = NaN
  ~~x = 0
2147483648
  Number(x) = 2147483648
  parseInt(x, 10) = 2147483648
  parseFloat(x) = 2147483648
  +x = 2147483648
  ~~x = -2147483648
4999999999
  Number(x) = 4999999999
  parseInt(x, 10) = 4999999999
  parseFloat(x) = 4999999999
  +x = 4999999999
  ~~x = 705032703

Các ~~xkết quả phiên bản trong một số trong "nhiều hơn" trường hợp, nơi những người khác thường dẫn đến undefined, nhưng nó không cho vào không hợp lệ (ví dụ như nó sẽ trở lại 0nếu chuỗi chứa ký tự không phải số sau khi một số hợp lệ).

Tràn ra

Xin lưu ý: Tràn số nguyên và / hoặc cắt bớt bit có thể xảy ra với ~~, nhưng không xảy ra với các chuyển đổi khác. Mặc dù việc nhập các giá trị lớn như vậy là không bình thường, nhưng bạn cần lưu ý điều này. Đã cập nhật ví dụ để bao gồm các giá trị lớn hơn nhiều.

Một số thử nghiệm Perf chỉ ra rằng tiêu chuẩn parseIntparseFloatchức năng thực sự là những lựa chọn nhanh nhất, có lẽ được trình duyệt tối ưu hóa cao, nhưng tất cả phụ thuộc vào yêu cầu của bạn vì tất cả các tùy chọn đều đủ nhanh : http://jsperf.com/best-of-string-to -number-chuyển đổi / 37

Tất cả điều này phụ thuộc vào cách cấu hình các bài kiểm tra hiệu suất vì một số hiển thị parseInt / parseFloat chậm hơn nhiều.

Lý thuyết của tôi là:

  • Dối trá
  • Darn dòng
  • Số liệu thống kê
  • Kết quả JSPerf :)

3
Hãy thực sự cẩn thận đối với các số lớn hơn 2147483647. ví dụ: ~~4294967296trả về 0.
Joseph Goh

@JosephGoh: Khi có cơ hội, tôi sẽ mở rộng kết quả để bao gồm tràn phạm vi int. Nói chung, nếu số lượng lớn như vậy, bạn có một giao diện rất đặc biệt đang diễn ra, vì vậy sẽ cần phải lưu ý về việc tràn. Cheers
Gone Coding

@JosephGoh: Thật thú vị, trong Chrome, bạn không nhận được số 0, bạn nhận được số âm vượt quá giá trị tối đa đã ký. Sau đó, nó dường như chỉ đơn giản là giảm các bit thừa khi bạn vượt quá giá trị tối đa int không dấu. ví dụ: "4999999999" => 705032703
Gone Coding

8

Đặt tiền tố chuỗi bằng +toán tử.

console.log(+'a') // NaN
console.log(+'1') // 1
console.log(+1) // 1

7

Một cách nhanh chóng để chuyển đổi chuỗi thành số nguyên là sử dụng bitwise hoặc, như sau:

x | 0

Mặc dù nó phụ thuộc vào cách nó được thực hiện, nhưng về lý thuyết, nó phải tương đối nhanh (ít nhất là nhanh nhất +x) vì trước tiên nó sẽ truyền xđến một số và sau đó thực hiện một hoặc rất hiệu quả.


Có, nhưng tôi tin rằng kỹ thuật này cắt bớt các số nguyên lớn, điều đó khá tệ. Cần lưu ý, tôi cũng có thể được sử dụng thay vì Math.floor (), nhưng với cùng một vấn đề.
Jean,

Đây là một jsperf của các toán tử bitwise khác nhau kết hợp với các phương thức trong câu trả lời đầu tiên. Tôi đã sắp xếp thứ tự ngẫu nhiên vì tôi thấy rằng một số trình duyệt sẽ tối ưu hóa thử nghiệm tiếp theo dựa trên mã tương tự từ thử nghiệm trước. Không giống như người trả lời hàng đầu, tôi thấy rằng ngầm định là phương pháp tồi tệ nhất.
Sao Diêm Vương

4

Đây là cách đơn giản để làm điều đó: var num = Number (str); trong ví dụ này, str là biến chứa chuỗi. Bạn có thể thử nghiệm và xem nó hoạt động như thế nào khi mở: Công cụ dành cho nhà phát triển Google chrome , sau đó đi tới bảng điều khiển và dán mã sau. đọc các bình luận để hiểu rõ hơn về cách chuyển đổi được thực hiện.

// Here Im creating my variable as a string
var str = "258";


// here im printing the string variable: str
console.log ( str );


// here Im using typeof , this tells me that the variable str is the type: string
console.log ("The variable str is type: " + typeof str);


// here is where the conversion happens
// Number will take the string in the parentesis and transform it to a variable num as type: number
var num = Number(str);
console.log ("The variable num is type: " + typeof num);

4

Tôi thấy rằng điều đó num * 1đơn giản, rõ ràng và phù hợp với các số nguyên và phao ...


3

Điều này có lẽ không nhanh, nhưng có lợi ích bổ sung là đảm bảo số của bạn ít nhất là một giá trị nhất định (ví dụ: 0), hoặc nhiều nhất là một giá trị nhất định:

Math.max(input, 0);

Nếu bạn cần đảm bảo một giá trị tối thiểu, thông thường bạn sẽ

var number = Number(input);
if (number < 0) number = 0;

Math.max(..., 0) giúp bạn không phải viết hai câu lệnh.


Tại sao không sử dụng Math.abs(input)? Nó cũng chuyển đổi chuỗi thành số dương và lưu thêm một vài ký tự.
Aaron Gillion

1
@AaronGillion: Math.max (-5, 0) sẽ trả về 0; Math.abs (-5) sẽ trả về 5. Tùy thuộc vào trường hợp sử dụng mà có ý nghĩa hơn.
Dan Dascalescu

1
Ồ, rất tiếc, trường hợp sử dụng của tôi rất khác trong bất kỳ đêm muộn nào tôi viết nhận xét đó.
Aaron Gillion

Nếu inputkhông thể chuyển đổi thành số bạn sẽ nhận đượcNaN
Domas Tháng 3

0

Bạn có thể thử sử dụng UnitOf , một thư viện đo lường và chuyển đổi kiểu dữ liệu mà chúng tôi vừa chính thức phát hành! UnitOf siêu nhanh, kích thước nhỏ và hiệu quả trong việc chuyển đổi bất kỳ kiểu dữ liệu nào mà không bao giờ gặp lỗi hoặc null / undefined. Giá trị mặc định bạn xác định hoặc giá trị mặc định của UnitOf được trả về khi chuyển đổi không thành công.

//One liner examples
UnitOf.DataType("12.5").toFloat(); //12.5 of type Float is returned. 0 would be returned if conversion failed.
UnitOf.DataType("Not A Num").toInt(10); //10 of type Int is returned as the conversion failed.

//Or as a variable
var unit = UnitOf.DataType("12.5");
unit.toInt(5); //12.5 of type Float is returned. 5 would be returned if the conversion failed.
unit.toFloat(8); // 12 of type Int is returned. 8 would be returned if the conversion failed.

0

Cách nhanh nhất là sử dụng -0:

const num = "12.34" - 0;
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.