วิธีที่ถูกต้องในการตรวจสอบความเท่าเทียมกันของสตริงใน JavaScript คืออะไร?


842

วิธีที่ถูกต้องในการตรวจสอบความเท่าเทียมกันระหว่าง Strings ใน JavaScript คืออะไร?


2
มีเหตุผลที่จะไม่ใช้ ==?
Kendrick

21
@ เคนดริค - แน่นอน มันเป็นระบบบังคับประเภทที่ใช้งานง่ายอย่างไม่น่าเชื่อและสามารถทำผิดพลาดได้ง่ายมาก ( ดูถูกแต่ผิดมาก)
STW

20
@Kendrick - เพราะหา{} == "[object Object]"ค่าได้จริงเช่น
Chetan Sastry

12
ค่อนข้างน่ารำคาญที่String().equals()ไม่ได้เป็นวิธีการใน JS แล้ว ...
อเล็กซานเด Mills

2
@AlexanderMills ทำไม
Ry-

คำตอบ:


624

เสมอจนกว่าคุณจะเข้าใจความแตกต่างและความหมายของการใช้==และ===โอเปอเรเตอร์ให้ใช้===โอเปอเรเตอร์เพราะมันจะช่วยให้คุณประหยัดจากข้อผิดพลาด (ไม่ชัดเจน) และ WTF ตัวดำเนินการ "ปกติ"==สามารถมีผลลัพธ์ที่ไม่คาดคิดได้มากเนื่องจากการบังคับประเภทภายในเพื่อใช้===เป็นแนวทางที่แนะนำเสมอ

สำหรับข้อมูลเชิงลึกเกี่ยวกับเรื่องนี้และส่วนอื่น ๆ ของ "ดีกับไม่ดี" ของจาวาสคริปต์อ่านได้ที่ Mr. Douglas Crockford และงานของเขา มี Google Tech Talk ที่ยอดเยี่ยมที่เขาสรุปข้อมูลที่ดีมากมาย: http://www.youtube.com/watch?v=hQVTIJBZook


ปรับปรุง:

ซีรี่ส์The Don't Don't Know JSของ Kyle Simpson นั้นยอดเยี่ยม (และสามารถอ่านออนไลน์ได้ฟรี) ซีรีส์เข้าสู่ส่วนที่เข้าใจผิดโดยทั่วไปของภาษาและอธิบาย "ส่วนที่ไม่ดี" ที่ Crockford แนะนำให้คุณหลีกเลี่ยง โดยการทำความเข้าใจพวกเขาคุณสามารถใช้งานได้อย่างเหมาะสมและหลีกเลี่ยงหลุมพราง

หนังสือ " Up & Going " ประกอบด้วยหัวข้อเกี่ยวกับความเท่าเทียมโดยมีบทสรุปเฉพาะเรื่องเวลาที่จะใช้โอเปอเรเตอร์Loose ( ==) และเข้มงวด ( ===):

เพื่อต้มรายละเอียดมากมายให้เป็นเรื่องง่าย ๆ และช่วยให้คุณรู้ว่าจะใช้==หรือ===ในสถานการณ์ต่าง ๆ นี่เป็นกฎง่าย ๆ ของฉัน:

  • หากทั้งสองค่า (ด้าน aka) ในการเปรียบเทียบอาจจะเป็นtrueหรือfalseค่าหลีกเลี่ยงและการใช้งาน=====
  • หากค่าทั้งในการเปรียบเทียบอาจจะมีค่าเฉพาะเหล่านี้ ( 0, ""หรือ[]- อาร์เรย์ว่างเปล่า) หลีกเลี่ยงและการใช้งาน=====
  • ในทุกกรณีอื่น ๆ ==คุณปลอดภัยในการใช้งาน ไม่เพียง แต่จะปลอดภัยเท่านั้น แต่ในหลาย ๆ กรณีมันทำให้รหัสของคุณง่ายขึ้นในวิธีที่ช่วยเพิ่มความสามารถในการอ่าน

ฉันยังคงแนะนำการพูดคุยของ Crockford สำหรับนักพัฒนาที่ไม่ต้องการลงทุนเวลาเพื่อทำความเข้าใจกับ Javascript จริงๆ - เป็นคำแนะนำที่ดีสำหรับนักพัฒนาที่ทำงานใน Javascript ได้เป็นครั้งคราวเท่านั้น


7
ไม่จำเป็นเมื่อคุณแน่ใจว่าตัวถูกดำเนินการทั้งสองเป็นสตริงเช่นเมื่อใช้if (typeof foo == "string")
Marcel Korpel

25
@Marcel - ถูกต้อง แต่มันดีกว่าที่จะใช้===โอเปอเรเตอร์เสมอและไม่ต้องกังวลกับ "ฉันจริง ๆ ทั้งหมด 100% แน่นอนว่ามัน==จะทำงานเหมือนที่ฉันคิดว่ามันจะเป็นอย่างไร"
STW

7
@STW - ตัวอย่างหนึ่งว่าทำไม Crockford ไม่ใช่ alpha และ omega ของ JavaScript คือคำแนะนำของเขาที่จะไม่ใช้การเพิ่ม / ลดลงแบบไม่รวม ( ++/ --)
Marcel Korpel

10
และไม่เคยใช้++หรือ--หรือif/elseคำสั่งบรรทัดเดียวหรือcontinueหรือnewผู้ประกอบการหรือจำนวนอื่น ๆ ของการปฏิบัติรหัสอย่างถูกต้องตามกฎหมายที่ Crockford ได้ถือว่า "เป็นอันตราย" และแน่นอนไม่เคยแม้แต่จะคิดเกี่ยวกับการใช้evalหรือwithแม้แต่ความผิดพลาดของพวกเขาเป็นที่เข้าใจกันดี และคุณเห็น JS รุ่นต่อไปหรือไม่ ไวยากรณ์ที่เข้มงวดขึ้นและฟังก์ชั่นผู้ช่วยเหลือจำนวนหนึ่งซึ่งบางส่วนได้รับการลอยมาหลายปีเป็นเรื่องที่เราได้รับมาตลอดเวลา ไวยากรณ์ยังไม่ได้รับการพัฒนาเลย หาก Crockford อยู่เบื้องหลังสิ่งนี้มันก็เป็นเรื่องเลวร้าย
MooGoo

4
@CoffeeAddict - การทดสอบอย่างรวดเร็วใน JSFiddle ดูเหมือนจะไม่เห็นด้วย ทั้งสองแบบเป็นกรณี ๆ ไป: jsfiddle.net/st2EU
STW

204

หากคุณรู้ว่าพวกเขาเป็นสตริงแล้วไม่จำเป็นต้องตรวจสอบประเภท

"a" == "b"

อย่างไรก็ตามโปรดทราบว่าวัตถุสตริงจะไม่เท่ากัน

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

จะกลับเท็จ

เรียกใช้เมธอด valueOf () เพื่อแปลงเป็นแบบดั้งเดิมสำหรับวัตถุ String

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

จะกลับมาจริง


4
ขอบคุณสำหรับ JSS นั้นวัตถุสตริงสองตัวจะไม่เท่ากันยกเว้นว่าเป็นวัตถุเดียวกันโดยไม่คำนึงถึงค่า
Anurag

4
@JSS: นอกจากนี้new String("a") == "a"เป็นจริง (แต่จะไม่อยู่ด้วย===) เพราะด้านซ้ายมือจะถูกแปลงเป็นค่าสตริงดั้งเดิม
Matthew Crumley

5
@JSS: new String("a") == new String("a"), new String("a") === new String("b"), new String("a") === new String("a")จะกลับมาทั้งหมดfalseตั้งแต่คุณจัดการกับการอ้างอิงไปยังวัตถุของชั้นไม่วิทยาการประเภทString string
palswim

4
เพียงชี้แจงให้ทุกคนได้อ่าน new String(foo)สร้างวัตถุสตริงและString(foo) แปลง foo เป็นสายอักขระดั้งเดิม
Brigand

9
@FakeRainBrigand - ชัดเจนเหมือนโคลน แต่นั่นคือสิ่งที่ javascripts เกี่ยวกับใช่ไหม?
Periata Breatta

58

นอกจากคำตอบเดียว: หากวิธีการทั้งหมดเหล่านี้ส่งคืนค่าเท็จแม้ว่าสตริงดูเหมือนว่าจะเท่ากันก็เป็นไปได้ว่ามีช่องว่างทางซ้ายและขวาของสตริงเดียว ดังนั้นให้ใส่.trim()ท้ายสตริงก่อนเปรียบเทียบ:

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

ฉันเสียเวลาหลายชั่วโมงในการหาว่ามีอะไรผิดปกติ หวังว่าสิ่งนี้จะช่วยให้ใครบางคน!


1
ขอบคุณมาก. มันแปลกสำหรับฉันเพราะฉันทำให้แน่ใจว่าไม่มีช่องว่างทางซ้ายหรือขวาและนี่เป็นวิธีเดียวที่จะแก้ปัญหาของฉัน บางทีมันอาจจะเกี่ยวข้องกับการเป็นตัวแทนภายในของสตริง?
Niko

2
ขอบคุณ @ akelec !! @Niko อาจเป็นเพราะตัวละคร Zero-Width-Space ซึ่งมองไม่เห็นด้วยตาเปล่า ดูen.wikipedia.org/wiki/Zero-width_space แม้ว่าตัวละครนี้จะมีจุดประสงค์นักพัฒนาจำนวนมากก็ยังคงไม่พอใจ!
stwr667

ขอบคุณที่ทำลายเนื่องจากการตรวจสอบความเท่าเทียมกันในของฉันถ้าล้มเหลว แต่ฉันไม่เห็นช่องว่างเมื่อตรวจสอบในขณะที่ตรวจแก้จุดบกพร่อง
drzounds

ปัญหาที่พบบ่อยเมื่อโหลดตัวแปรจากไฟล์ข้อความ (เช่น: ใช้fetch) ขอบคุณมาก.
Sopalajo de Arrierez

@SopalajodeArrierez ตรงส่วนใหญ่จะมีช่องว่างหรือการขึ้นบรรทัดใหม่ที่ส่วนท้ายของสตริง ยินดี.
akelec

22

สิ่งที่ทำให้ฉันมีคำถามนี้คือpaddingและwhite-spaces

ตรวจสอบกรณีของฉัน

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

และชื่อเรื่องคือ " LastName"

ป้อนคำอธิบายรูปภาพที่นี่

ดังนั้นคุณอาจต้องใช้trimฟังก์ชั่นเช่นนี้

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

2
ขอบคุณเหมือนกันที่นี่ฉันใช้ .toString().trim()ใน
Typescript

17

นอกจากว่าคุณจะรู้ว่าการข่มขู่ทำงานอย่างไรคุณควรหลีกเลี่ยง==และใช้ตัวดำเนินการประจำ===ตัวแทน แต่คุณควรอ่านเพื่อทำความเข้าใจว่ามันทำงานอย่างไร

หากคุณใช้==คุณปล่อยให้ภาษาทำการบีบบังคับบางประเภทให้กับคุณตัวอย่างเช่น:

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

ดังที่ Douglas Crockford พูดไว้ในหนังสือของเขา:

ควรใช้ตัวดำเนินการประจำตัวดีกว่าเสมอ


3
แม้ว่าลิงก์นี้อาจตอบคำถามได้ดีกว่าหากรวมส่วนสำคัญของคำตอบไว้ที่นี่และให้ลิงก์สำหรับการอ้างอิง คำตอบสำหรับลิงค์เท่านั้นอาจไม่ถูกต้องหากหน้าเว็บที่เชื่อมโยงนั้นเปลี่ยนแปลง
Parkash Kumar

{}==" "ให้Unexpected token ==วิธีที่ถูกต้องในการทำกับฉัน
Basheer AL-MOMANI

12

จริงๆแล้วมีสองวิธีที่สตริงสามารถสร้างเป็นจาวาสคริปต์

  1. var str = 'Javascript'; สิ่งนี้จะสร้างค่าสตริงดั้งเดิม

  2. var obj = new String('Javascript');Stringนี้จะสร้างวัตถุเสื้อคลุมประเภท

    typeof str // string
    typeof obj // object

ดังนั้นวิธีที่ดีที่สุดในการตรวจสอบความเท่าเทียมกันคือการใช้ตัว===ดำเนินการเพราะมันจะตรวจสอบค่าเช่นเดียวกับชนิดของตัวถูกดำเนินการทั้งสอง

หากคุณต้องการตรวจสอบความเท่าเทียมกันระหว่างวัตถุสองรายการการใช้String.prototype.valueOfเป็นวิธีที่ถูกต้อง

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


1

พิจารณาว่าทั้งสองสายอาจมีขนาดใหญ่มากมี 2 วิธีหลักbitwise searchและlocaleCompare

ฉันแนะนำฟังก์ชั่นนี้อีกครั้ง

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

-2

วิธีที่ง่ายที่สุดในการทำคือใช้ผู้ประกอบการที่ประกอบไปด้วย:

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

แต่ถ้าสตริงที่คุณต้องการเปรียบเทียบอยู่ในอาร์เรย์คุณจะใช้ตัวกรอง es6

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

ด้านบนจะตรวจสอบ stringArray ของคุณและสตริงที่ตรงกับจากอาร์เรย์ซึ่งในกรณีของเราเราเลือก "เด็กชาย"


-8

ฉันมากับโซลูชันทางเลือกระหว่างการทดสอบ คุณสามารถใช้ฟังก์ชันกับต้นแบบสตริง

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

ทำงานได้ดีในเบราว์เซอร์ Chrome


คำถามถามว่าจะตรวจสอบได้อย่างไรว่า "hello world" = "hello world" ไม่ใช่วิธีการตรวจสอบว่า "hello world" เป็นสตริงหรือไม่
Nick

4
นี่มันช่างงี่เง่า คุณได้สร้าง Rube Goldberg เวอร์ชัน==แล้ว
JJJ

สวัสดี OP การแก้ไขของคุณแตกต่างอย่างสิ้นเชิงในส่วนของจิตวิญญาณและคำตอบของคุณมีจำนวนมากเกินไป ฉันขอให้คุณโปรดลบคำตอบนี้และโพสต์คำตอบใหม่ด้วยฉบับแก้ไขของคุณ
Yılmaz Durmaz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.