Cách chính xác để kiểm tra tính bằng chuỗi trong JavaScript là gì?


844

Cách chính xác để kiểm tra sự bằng nhau giữa các Chuỗi trong JavaScript là gì?


2
Có một lý do để không sử dụng ==?
Kendrick

21
@Kendrick - chắc chắn rồi. Hệ thống cưỡng chế kiểu này có thể cực kỳ không trực quan và có thể rất dễ mắc lỗi (có vẻ đúng, nhưng có thể rất sai)
STW

20
@Kendrick - vì {} == "[object Object]"đánh giá là đúng, chẳng hạn.
Chetan Sastry

12
hơi khó chịu đó String().equals()không phải là một phương pháp trong JS ...
Alexander Mills

2
@AlexanderMills Tại sao?
Ry-

Câu trả lời:


624

luôn luôn Cho đến khi bạn hiểu đầy đủ về sự khác biệt và ý nghĩa của việc sử dụng cáctoán tử=====toán tử, hãy sử dụng===toán tử vì nó sẽ cứu bạn khỏi các lỗi và các WTF tối nghĩa (không rõ ràng). ==Toán tử"thông thường"có thể có kết quả rất bất ngờ do loại cưỡng chế trong nội bộ, vì vậy sử dụng===luôn là phương pháp được khuyến nghị.

Để hiểu rõ hơn về điều này và các phần "tốt so với xấu" khác của Javascript, hãy đọc về ông Douglas Crockford và công việc của ông. Có một Google Tech Talk tuyệt vời nơi anh ấy tóm tắt rất nhiều thông tin hay: http://www.youtube.com/watch?v=hQVTIJBZook


Cập nhật:

Các bạn không biết JS loạt bởi Kyle Simpson là tuyệt vời (và miễn phí để đọc trên mạng). Loạt bài đi vào các lĩnh vực thường bị hiểu sai về ngôn ngữ và giải thích "những phần xấu" mà Crockford gợi ý bạn nên tránh. Bằng cách hiểu chúng, bạn có thể sử dụng chúng đúng cách và tránh những cạm bẫy.

Cuốn sách " Lên & Đi " bao gồm một phần về Bình đẳng , với bản tóm tắt cụ thể này về thời điểm sử dụng toán tử lỏng ( ==) so với nghiêm ngặt ( ===):

Để tổng hợp rất nhiều chi tiết cho một vài thao tác đơn giản và giúp bạn biết nên sử dụng ==hay ===trong các tình huống khác nhau, đây là các quy tắc đơn giản của tôi:

  • Nếu một trong hai giá trị (còn gọi là bên) trong một so sánh có thể là giá trị truehoặc falsegiá trị, hãy tránh ==và sử dụng ===.
  • Nếu một trong hai giá trị trong một so sánh có thể là các giá trị cụ thể ( 0, ""hoặc []- mảng trống), tránh ==và sử dụng ===.
  • Trong tất cả các trường hợp khác, bạn an toàn để sử dụng ==. Không chỉ an toàn, mà trong nhiều trường hợp, nó đơn giản hóa mã của bạn theo cách cải thiện khả năng đọc.

Tôi vẫn khuyên bạn nên nói chuyện với Crockford cho các nhà phát triển, những người không muốn đầu tư thời gian để thực sự hiểu Javascript, đó là lời khuyên tốt cho nhà phát triển chỉ thỉnh thoảng làm việc trong Javascript.


7
Không cần thiết khi bạn chắc chắn cả hai toán hạng đều là chuỗi, ví dụ: khi sử dụngif (typeof foo == "string")
Marcel Korpel

25
@Marcel - bạn đã đúng, nhưng sẽ tốt hơn nhiều khi luôn sử dụng ===toán tử và không bao giờ phải lo lắng về "tôi thực sự, hoàn toàn, chắc chắn 100% ==sẽ hành xử theo cách tôi nghĩ?"
STW

7
@STW - một ví dụ tại sao Crockford không phải là alpha và omega của JavaScript, là lời khuyên của anh ấy không nên sử dụng tăng / giảm đơn phương ( ++/ --).
Marcel Korpel

10
Và không bao giờ sử dụng ++hoặc --hoặc các if/elsecâu lệnh đơn continuehoặc newnhà điều hành hoặc bất kỳ số thực hành mã hoàn toàn hợp pháp nào khác mà Crockford đã coi là "có hại". Và tất nhiên không bao giờ thậm chí xem xét suy nghĩ về việc sử dụng evalhoặc withngay cả khi những cạm bẫy của họ được hiểu rõ. Và bạn đã thấy phiên bản tiếp theo của JS chưa? Cú pháp chặt chẽ hơn và một số ít các hàm trợ giúp, một số đã trôi nổi trong nhiều năm, là tất cả những gì chúng ta nhận được sau tất cả thời gian này. Cú pháp đã không phát triển chút nào. Nếu Crockford đứng sau điều này, thì đó là một điều tồi tệ.
MooGoo

4
@CoffeeAddict - một thử nghiệm nhanh trong JSFiddle dường như không đồng ý. Cả hai đều phân biệt chữ hoa chữ thường: jsfiddle.net/st2EU
STW

205

Nếu bạn biết chúng là các chuỗi, thì không cần phải kiểm tra loại.

"a" == "b"

Tuy nhiên, lưu ý rằng các đối tượng chuỗi sẽ không bằng nhau.

new String("a") == new String("a")

sẽ trả lại sai.

Gọi phương thức valueOf () để chuyển đổi nó thành nguyên hàm cho các đối tượng String,

new String("a").valueOf() == new String("a").valueOf()

sẽ trở lại đúng


4
cảm ơn vì JSS đó, hai đối tượng chuỗi sẽ không bao giờ bằng nhau trừ khi chúng là cùng một đối tượng bất kể giá trị.
Anurag

4
@JSS: Ngoài ra, new String("a") == "a"là đúng (nhưng sẽ không đúng ===), vì phía bên trái sẽ được chuyển đổi thành giá trị chuỗi nguyên thủy.
Matthew Crumley

5
@JSS: new String("a") == new String("a"), new String("a") === new String("b"), new String("a") === new String("a")tất cả sẽ trở lại false, kể từ khi bạn đang làm việc với tài liệu tham khảo để các đối tượng của Stringlớp, không phải nguyên thủy loại string.
palswim

4
Chỉ cần làm rõ điều này cho bất cứ ai đọc nó. new String(foo)tạo một đối tượng chuỗi và String(foo) chuyển đổi foo thành một chuỗi nguyên thủy.
Brigand

9
@FakeRainBrigand - rõ ràng như bùn, nhưng đó là những gì javascripts nói, phải không?
Periata Breatta

58

Chỉ cần một bổ sung cho câu trả lời: Nếu tất cả các phương thức này trả về false, ngay cả khi các chuỗi dường như bằng nhau, có thể có một khoảng trắng ở bên trái và hoặc bên phải của một chuỗi. Vì vậy, chỉ cần đặt một .trim()ở cuối chuỗi trước khi so sánh:

if(s1.trim() === s2.trim())
{
    // your code
}

Tôi đã mất hàng giờ để cố gắng tìm ra những gì sai. Hy vọng điều này sẽ giúp cho một ai đó!


1
Cảm ơn rất nhiều. Nó là lạ đối với tôi, bởi vì tôi chắc chắn rằng không có khoảng trắng ở bên trái hoặc bên phải và đây vẫn là cách duy nhất để giải quyết vấn đề của tôi. Có lẽ nó liên quan đến biểu diễn bên trong của một chuỗi?
Niko

2
Cảm ơn @akelec !! @Niko, có khả năng là do nhân vật Zero-Width-Space không thể nhìn thấy bằng mắt thường. Xem en.wikipedia.org/wiki/Zero- thong_space . Mặc dù nhân vật này có mục đích của nó, nhiều nhà phát triển phẫn nộ với sự tồn tại của nó!
stwr667

Cảm ơn bạn đã bực bội kể từ khi kiểm tra bình đẳng nếu thất bại nhưng tôi không thấy khoảng trắng khi kiểm tra trong khi gỡ lỗi.
drzound

Một vấn đề phổ biến khi tải một biến từ tệp văn bản (nghĩa là: sử dụng fetch). Cảm ơn rất nhiều.
Sopalajo de Arrierez

@SopalajodeArrierez, chính xác, chủ yếu là một khoảng trống hoặc trở lại vận chuyển ở cuối chuỗi. Không có gì.
akelec

22

điều gì dẫn tôi đến câu hỏi này là paddingwhite-spaces

kiểm tra trường hợp của tôi

 if (title === "LastName")
      doSomething();

và tiêu đề là " LastName"

nhập mô tả hình ảnh ở đây

vì vậy có lẽ bạn phải sử dụng trimchức năng như thế này

var title = $(this).text().trim();

2
Cảm ơn tương tự ở đây tôi đã sử dụng .toString().trim()trong
Bản mô tả

17

Trừ khi bạn thực sự biết cách thức hoạt động cưỡng chế, bạn nên tránh ==và sử dụng toán tử nhận dạng ===thay thế. Nhưng bạn nên đọc nó để hiểu làm thế nào nó hoạt động .

Nếu bạn sử dụng ==, bạn để ngôn ngữ thực hiện một số kiểu ép buộc cho bạn, ví dụ:

"1" == 1 // true
"0" == false // true
[] == false // true

Như Douglas Crockford's đã nói trong cuốn sách của mình:

Luôn luôn sử dụng toán tử nhận dạng tốt hơn.


3
Mặc dù liên kết này có thể trả lời câu hỏi, tốt hơn là bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo. Câu trả lời chỉ liên kết có thể trở nên không hợp lệ nếu trang được liên kết thay đổi.
Parkash Kumar

{}==" "đã cho tôi Unexpected token ==cách chính xác để làm điều đó?
Basheer AL-MOMani

12

Thực tế, có hai cách để tạo chuỗi trong javascript.

  1. var str = 'Javascript'; Điều này tạo ra một giá trị chuỗi nguyên thủy.

  2. var obj = new String('Javascript');Điều này tạo ra một đối tượng bao bọc của loại String.

    typeof str // string
    typeof obj // object

Vì vậy, cách tốt nhất để kiểm tra sự bằng nhau là sử dụng ===toán tử vì nó kiểm tra giá trị cũng như loại của cả hai toán hạng.

Nếu bạn muốn kiểm tra sự bằng nhau giữa hai đối tượng thì sử dụng String.prototype.valueOflà cách chính xác.

new String('javascript').valueOf() == new String('javascript').valueOf()

6

Chuỗi Objectscó thể được kiểm tra bằng JSON.stringyfy()thủ thuật.

var me = new String("me");
var you = new String("me");
var isEquel = JSON.stringify(me) === JSON.stringify(you);
console.log(isEquel);


1

Xem xét rằng cả hai chuỗi có thể rất lớn, có 2 cách tiếp cận chính bitwise searchlocaleCompare

Tôi đề nghị chức năng này

function compareLargeStrings(a,b){
    if (a.length !== b.length) {
         return false;
    }
    return a.localeCompare(b) === 0;
}

-2

Cách dễ nhất để làm điều đó là sử dụng một toán tử ternary như vậy:

 "was" == "was" ? true : false

nhưng nếu chuỗi bạn muốn so sánh nằm trong một mảng, bạn sẽ sử dụng bộ lọc es6

let stringArray  = ["men", "boys", "girls", "sit", "can", "gotten"]
stringArray.filter(I=> I === boys ? 
stringArray.pop(indexOf(I)) : null)

ở trên sẽ kiểm tra chuỗiArray của bạn và bất kỳ chuỗi nào khớp với nó từ mảng mà trong trường hợp của chúng tôi, chúng tôi đã chọn "boys"


-8

Tôi đã đưa ra một giải pháp thay thế trong quá trình thử nghiệm. bạn có thể sử dụng chức năng trên nguyên mẫu chuỗi.

String.prototype.betwenStr = function(one){

return JSON.stringify(new String(this)) === JSON.stringify(new String(one));

}


 //call it
 "hello world".betweenStr("hello world"); //returns boolean 
 //value

hoạt động tốt trong trình duyệt chrome


Câu hỏi hỏi làm thế nào để kiểm tra xem "hello world" = "hello world", không phải cách kiểm tra xem "hello world" có phải là một chuỗi không.
Nick

4
Điều này chỉ là ngớ ngẩn. Bạn đã tạo một phiên bản Rube Goldberg ==.
JJJ

Xin chào OP, phần chỉnh sửa của bạn hoàn toàn khác biệt về phần tinh thần và câu trả lời của bạn đã có quá nhiều ý kiến ​​trái chiều. Tôi mong bạn vui lòng xóa câu trả lời này và đăng một câu trả lời mới với phiên bản đã chỉnh sửa của bạn
Yılmaz Durmaz
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.