เหตุใด“ true” == true จึงแสดงเท็จใน JavaScript


90

MDC อธิบายตัว==ดำเนินการดังนี้ :

หากตัวถูกดำเนินการทั้งสองไม่ใช่ประเภทเดียวกัน JavaScript จะแปลงตัวถูกดำเนินการจากนั้นใช้การเปรียบเทียบที่เข้มงวด ถ้าตัวถูกดำเนินการเป็นตัวเลขหรือบูลีนตัวถูกดำเนินการจะถูกแปลงเป็นตัวเลขถ้าเป็นไปได้ มิฉะนั้นถ้าตัวถูกดำเนินการเป็นสตริงตัวถูกดำเนินการอื่นจะถูกแปลงเป็นสตริงถ้าเป็นไปได้

ด้วยเหตุนี้ฉันจะประเมิน"true" == trueดังนี้:

  1. เป็นประเภทเดียวกันหรือไม่? ไม่
  2. ตัวถูกดำเนินการเป็นตัวเลขหรือบูลีน? ใช่
  3. เราสามารถแปลงทั้งสองเป็นตัวเลขได้หรือไม่? ไม่ ( isNaN(Number("true")) // true)
  4. ตัวถูกดำเนินการเป็นสตริงหรือไม่ ใช่
  5. เราสามารถแปลงตัวถูกดำเนินการอื่นเป็นสตริงได้หรือไม่? ใช่ ( String(true) === "true" // true)

ฉันลงเอยด้วยสตริง"true"และ"true"ซึ่งควรประเมินtrueแต่ JavaScript แสดงเท็จ

ฉันพลาดอะไรไป?


เกี่ยวข้อง: es5.github.com/#x11.9.1
zzzzBov

6
ด้วย JavaScript มากมายทั่วโลกจึงเป็นสถานที่ที่น่ากลัว: if("true" == true) {console.log("yes")} else {console.log("no")}; if("true") {console.log("yes")} else {console.log("no")}---> "ไม่ใช่"
user1068352

1
ฉันต้องบอกว่าฉันประหลาดใจและนั่นก็โง่มากที่เกิดเหตุการณ์นี้ขึ้น อีกเหตุผลหนึ่งที่มักจะใช้เสมอ ===
BT

@ user1068352 ตรวจสอบความวุ่นวาย :) dorey.github.io/JavaScript-Equality-Table
João Pimentel Ferreira

คำตอบ:


89

เพราะ "true"จะถูกแปลงเป็นNaNในขณะที่จะถูกแปลงเป็นtrue 1ดังนั้นพวกเขาจึงแตกต่างกัน

เช่นเดียวกับที่คุณรายงานทั้งสองอย่างจะถูกแปลงเป็นตัวเลขเพราะอย่างน้อยก็trueสามารถเป็น (ดูความคิดเห็นของ Erik Reppen) แล้วเปรียบเทียบกัน


คุณบอกฉันได้ไหมว่าเมื่อไหร่ขั้นตอนCan we convert both to a number?จะเป็นเท็จ? ถ้าแม้NaNเป็นตัวเลขขั้นตอนนี้จะล้มเหลวได้อย่างไร?
Isaac

5
อย่างใดอย่างหนึ่งกับไม่ หากทั้งสองอย่างส่งผลให้เกิด NaN พวกเขาจะเปลี่ยนเป็นการประเมินสตริง หากแปลงได้เพียงตัวเดียวก็ยังมีการเปรียบเทียบตัวเลข
Erik Reppen

2
มีวัตถุแปลก ๆ บางอย่างใน Javascript ที่ทำงานได้ค่อนข้างแปลก ตัวอย่างเช่นเอกสาร XML ใน IE <9 ทำให้เกิดข้อผิดพลาดเมื่อคุณพยายามแปลงเป็นตัวเลข
MaxArt

คุณสามารถดูการแปลงได้ด้วยตัวคุณเองNumber(true)และNumber('true')
Erik Reppen

11

ตัว==ดำเนินการเปรียบเทียบถูกกำหนดใน ECMA 5เป็น:

  1. ถ้าType (x) เป็น Number และType (y) เป็น String ให้
    ส่งคืนผลลัพธ์ของการเปรียบเทียบ x == ToNumber (y)
  2. ถ้าType (x) เป็น String และType (y) คือ Number ให้
    ส่งคืนผลลัพธ์ของการเปรียบเทียบToNumber (x) == y
  3. ถ้าType (x) เป็นบูลีนให้ส่งคืนผลลัพธ์ของการเปรียบเทียบToNumber (x) == y
  4. ถ้าType (y) เป็นบูลีนให้ส่งคืนผลลัพธ์ของการเปรียบเทียบ x == ToNumber (y)

ดังนั้น "true" == true จึงถูกประเมินเป็น:

  1. "true" == ToNumber (จริง)   (ผ่านกฎ 7)
  2. "จริง" == 1
  3. ToNumber ("จริง") == 1   (ผ่านกฎ 5)
  4. NaN == 1

===> เท็จ


3

ตามอัลกอริทึมการเปรียบเทียบความเท่าเทียมกันเชิงนามธรรม

http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3

หากตัวเลือกใดตัวหนึ่งเป็นบูลีนและอื่น ๆ ไม่ใช่บูลีนคือตัวแปลงเป็นหมายเลข 0 หรือ 1 ดังนั้นจึงtrue == "true"เป็นเท็จ


ฉันสรุปถูกต้องด้วยวิธีต่อไปนี้หรือไม่? "true" == true กลายเป็น "true" == 1 แล้วกลายเป็น "true" == "1" นั่นเป็นเหตุผลว่าทำไมจึงคืนค่า false?
vuquanghoang
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.