Truyền tới chuỗi trong JavaScript


184

Tôi đã tìm thấy ba cách để truyền một biến Stringvào JavaScript.
Tôi đã tìm kiếm ba tùy chọn đó trong mã nguồn jQuery và tất cả chúng đều được sử dụng .
Tôi muốn biết nếu có bất kỳ sự khác biệt giữa chúng:

value.toString()
String(value)
value + ""

BẢN GIỚI THIỆU

Tất cả đều sản xuất cùng một đầu ra, nhưng liệu một trong số họ tốt hơn những sản phẩm khác?
Tôi có thể nói rằng + ""có một lợi thế là nó cứu được một số nhân vật, nhưng đó không phải là lợi thế lớn, còn gì nữa không?


1
Dường như với tôi rằng nếu tất cả mọi thứ đều bình đẳng, tiêu chuẩn toString()sẽ là con đường để đi.
asawyer

1
@asawyer. Và tại sao vậy? Nếu tất cả chúng đều tạo ra cùng một đầu ra và làm như vậy, hãy chọn một và đi với nó. Đây là ý kiến ​​của tôi nếu đây thực sự là trường hợp ở đây .
gdoron đang hỗ trợ Monica

1
Hai phương thức đầu tiên phải tương đương (bạn nên kiểm tra tiêu chuẩn nhưng hàm tạo sẽ gọi toString). Cái thứ 3 USUALLY tạo ra cùng một đầu ra nhưng nó bao gồm một cơ chế rất khác nhau (bên cạnh tốc độ, nó liên quan đến các cuộc gọi khác nhau nên nó có thể không phải là điều bạn mong đợi cho mọi loại đối tượng).
Adriano Repetti

6
Theo tôi về mặt toStringngữ nghĩa là cách rõ ràng nhất để tự ghi lại sự thật rằng bạn đang cố gắng để có được một chuỗi tương đương với một đối tượng. String(...)là một chút khó hiểu, và value + ""là một chút hack. Nó cũng cung cấp cho bạn khả năng ghi đè mặc định toStringbằng cách triển khai tùy chỉnh nếu bạn cho rằng tôi cần, như một lợi ích phụ nhỏ.
asawyer

2
@Adriano. Nhưng + ""là nhanh nhất theo jsperf, vì vậy ... nó thực sự là một số cách khác tôi đoán.
gdoron đang hỗ trợ Monica

Câu trả lời:


212

Họ cư xử khác nhau khi valuenull.

  • null.toString()ném lỗi - Không thể gọi phương thức 'toString' của null
  • String(null)trả về - "null"
  • null + ""cũng trả về - "null"

Hành vi rất giống xảy ra nếu valueundefined(xem câu trả lời của jbabey ).

Ngoài ra, có một sự khác biệt hiệu suất không đáng kể, trừ khi bạn sử dụng chúng trong các vòng lặp lớn, không đáng lo ngại.


Đây thực sự là một sự khác biệt thú vị. Vì vậy, bạn không nên sử dụng toString()khi chưa kiểm tra null.
Sammy S.

@SammyS. không biết in nullhay undefinedlên màn hình là hành vi đáng mong đợi hơn thì lỗi javascript ...
Justus Romijn

@JustusRomijn: Đúng thật. Trong khi đó, tôi bắt đầu sử dụng loại Tùy chọn để xử lý các lỗi đó.
Sammy S.

bạn có thể kiểm tra bất kỳ biến nào trong số các biến được đúc này bằng typeof để kiểm tra chuỗi. typeof (null + '') == 'chuỗi'
Bruce Lim

4
Có một trường hợp khác khi họ cư xử khác nhau. v + ''trả về kết quả không chính xác nếu v có cả hai phương thức toString () và valueOf (). Sự kết hợp sẽ bỏ qua toString () và sẽ sử dụng valueOf (). Ví dụ về một lớp học mà nối thất bại: github.com/processing-js/processing-js/blob/...
Mikita Belahlazau

26

Có sự khác biệt, nhưng có lẽ chúng không liên quan đến câu hỏi của bạn. Ví dụ: nguyên mẫu toString không tồn tại trên các biến không xác định, nhưng bạn có thể truyền không xác định vào một chuỗi bằng hai phương thức khác:

var foo;

var myString1 = String(foo); // "undefined" as a string

var myString2 = foo + ''; // "undefined" as a string

var myString3 = foo.toString(); // throws an exception

http://jsfiddle.net/f8YwA/


3
Nếu một biến hoàn toàn không được xác định, bạn vẫn sẽ gặp lỗi String(). Ví dụ: String(test);ném Uncaught ReferenceError: test is not defined, trong khi var test; String(test);sẽ dẫn đến "undefined".
Anthony

17

Chúng hoạt động giống nhau nhưng toStringcũng cung cấp một cách để chuyển đổi một chuỗi nhị phân, bát phân hoặc thập lục phân:

Thí dụ:

var a = (50274).toString(16)  // "c462"
var b = (76).toString(8)      // "114"
var c = (7623).toString(36)   // "5vr"
var d = (100).toString(2)     // "1100100"

9

Theo thử nghiệm JSPerf này , chúng khác nhau về tốc độ. Nhưng trừ khi bạn sẽ sử dụng chúng với số lượng lớn, bất kỳ trong số chúng sẽ hoạt động tốt.

Để hoàn thiện: Như asawyer đã đề cập, bạn cũng có thể sử dụng .toString()phương pháp.


2
Cái jsperf đó có cùng một bài kiểm tra hai lần, tôi đã chỉnh sửa nónew String()trả về một đối tượng không phải làString
gdoron đang hỗ trợ Monica

new String()trả về một đối tượng có String()tuy nhiên, trả về một chuỗi, đó là một chuỗi trong câu hỏi.
Connell

2
Điều này không hoàn toàn đúng. Như bạn có thể thấy từ các kết quả, nối một chuỗi rỗng và một đối tượng không mang lại kết quả tương tự như nối một đối tượng và một chuỗi rỗng. Hơn nữa, new String(blarg)cung cấp cho bạn một Stringđối tượng bạn có thể gọi toString()vào. Trong trình gỡ lỗi Chrome của tôi, chúng thực sự dẫn đến cùng một loại đối tượng ngoại trừ sự khác biệt đã nói.
Sammy S.

@SammyS. Bạn có thể vui lòng thêm kết quả thực hiện ví dụ vào câu trả lời của bạn? Liên kết jsperf hiện đang ngừng hoạt động và chắc chắn sẽ trở lại trong hơn 5 năm tới.
mxmlnkn

9

Ngoài tất cả những điều trên, người ta cần lưu ý rằng, đối với một giá trị được xác định v:

  • String(v) các cuộc gọi v.toString()
  • '' + vcác cuộc gọi v.valueOf()trước bất kỳ loại diễn viên nào khác

Vì vậy, chúng tôi có thể làm một cái gì đó như:

var mixin = {
  valueOf:  function () { return false },
  toString: function () { return 'true' }
};
mixin === false;  // false
mixin == false;    // true
'' + mixin;       // "false"
String(mixin)     // "true"

Đã thử nghiệm trong FF 34.0 và Nút 0.10


8

nếu bạn ổn với null, không xác định, NaN, 0 và false, tất cả chuyển sang '' thì (s ? s+'' : '')nhanh hơn.

xem http://jsperf.com/cast-to-opes/8

lưu ý - có sự khác biệt đáng kể giữa các trình duyệt tại thời điểm này.


4

Ví dụ trong thế giới thực: Tôi đã có một hàm nhật ký có thể được gọi với số lượng tham số tùy ý : log("foo is {} and bar is {}", param1, param2). Nếu một DEBUGcờ được đặt thành true, dấu ngoặc được thay thế bởi các tham số đã cho và chuỗi được truyền đến console.log(msg). Các tham số có thể và sẽ là Chuỗi, Số và bất cứ điều gì có thể được trả về bằng các lệnh gọi JSON / AJAX, thậm chí có thể null.

  • arguments[i].toString()không phải là một lựa chọn, vì các nullgiá trị có thể (xem câu trả lời của Connell Watkins)
  • JSLint sẽ phàn nàn về arguments[i] + "". Điều này có thể hoặc không thể ảnh hưởng đến quyết định sử dụng cái gì. Một số người tuân thủ nghiêm ngặt JSLint.
  • Trong một số trình duyệt, nối chuỗi rỗng nhanh hơn một chút so với sử dụng hàm chuỗi hoặc hàm tạo chuỗi (xem thử nghiệm JSPerf trong Sammys S. answer). Trong Opera 12 và Firefox 19, việc ghép các chuỗi trống nhanh hơn một cách nhanh chóng (95% trong Firefox 19) - hoặc ít nhất là JSPerf đã nói như vậy.

1

Trên trang này, bạn có thể tự kiểm tra hiệu suất của từng phương thức :)

http://jsperf.com/cast-to-opes/2

Ở đây, trên tất cả các máy và trình duyệt, ' "" + str ' là tốc độ nhanh nhất, (Chuỗi) là chậm nhất

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.