ในฐานะที่เป็นนักคณิตศาสตร์มืออาชีพที่ฉันเห็นในผู้ประกอบการเหมือนกันจาวาสคริปต์ไว้ของ ==
(หรือที่เรียกว่า "การเปรียบเทียบนามธรรม", "ความเท่าเทียมกันหลวม" ) ความพยายามที่จะสร้างความสมดุลระหว่างหน่วยงานซึ่งรวมถึงการสะท้อน , สมมาตรและสกรรมกริยา น่าเสียดายที่คุณสมบัติพื้นฐานสองในสามข้อนี้ล้มเหลว:
A == A
อาจเป็นเท็จเช่น
NaN == NaN // false
A == B
และB == C
กันไม่ได้หมายความว่าA == C
เช่น
'1' == 1 // true
1 == '01' // true
'1' == '01' // false
สถานที่ให้บริการสมมาตรเท่านั้นที่รอดชีวิต:
A == B
บอกเป็นนัยว่าB == A
การละเมิดใดที่ไม่อาจคิดได้ในกรณีใด ๆ และอาจนำไปสู่การกบฏที่ร้ายแรง;)
ทำไมความสัมพันธ์ที่เท่าเทียมกันมีความสำคัญ?
เพราะนั่นเป็นความสัมพันธ์ที่สำคัญและแพร่หลายที่สุดโดยมีตัวอย่างและแอพพลิเคชั่นมากมายให้การสนับสนุน แอพพลิเคชั่นที่สำคัญที่สุดคือการสลายตัวของเอนทิตีในคลาสที่เท่ากันซึ่งเป็นวิธีที่สะดวกและง่ายต่อการเข้าใจความสัมพันธ์ และความล้มเหลวที่จะเท่าเทียมนำไปสู่การขาดเรียนเทียบเท่าซึ่งจะนำไปสู่การขาดความหยั่งรู้และความซับซ้อนที่ไม่จำเป็นที่เป็นที่รู้จักกันดี
เหตุใดจึงเป็นความคิดที่น่ากลัวที่จะเขียน==
เพื่อความสัมพันธ์ที่ไม่เท่าเทียมกัน?
เพราะมันทำให้ความคุ้นเคยและสัญชาตญาณของเราแตกต่างกันไปตามความสัมพันธ์ที่น่าสนใจของความคล้ายคลึงกันความเท่าเทียมความสมภาคกันความสมมาตรมอร์ฟิซึ่มซเอกลักษณ์อื่น ๆ คือความเท่าเทียมกัน
การแปลงประเภท
แทนที่จะอาศัยความเท่าเทียมที่ใช้งานง่ายJavaScriptแนะนำการแปลงประเภท:
ตัวดำเนินการความเท่าเทียมกันจะแปลงตัวถูกดำเนินการหากพวกมันไม่ใช่ประเภทเดียวกันดังนั้นจึงใช้การเปรียบเทียบที่เข้มงวด
แต่การแปลงประเภทกำหนดไว้อย่างไร? ผ่านชุดของกฎที่ซับซ้อนที่มีข้อยกเว้นมากมายใช่ไหม
พยายามสร้างความสัมพันธ์ที่เท่าเทียมกัน
booleans ชัดเจนtrue
และfalse
ไม่เหมือนกันและควรอยู่ในคลาสที่แตกต่างกัน
เบอร์ โชคดีที่ความเท่าเทียมกันของตัวเลขนั้นถูกนิยามไว้อย่างดีแล้วซึ่งตัวเลขที่แตกต่างกันสองตัวนั้นไม่เคยอยู่ในระดับความเท่ากัน ในวิชาคณิตศาสตร์นั่นก็คือ ใน JavaScript ความคิดของจำนวนที่มีรูปร่างผิดปกติค่อนข้างผ่านการปรากฏตัวของแปลกใหม่มากขึ้น-0
, และInfinity
-Infinity
สัญชาตญาณทางคณิตศาสตร์ของเราบอกว่า0
และ-0
ควรอยู่ในระดับเดียวกัน (ในความ-0 === 0
เป็นจริงtrue
) ในขณะที่แต่ละ infinities เป็นชั้นแยก
ตัวเลขและบูลีน เมื่อกำหนดจำนวนคลาสเราจะวางบูลีนที่ไหน false
กลายเป็นคล้ายกับ0
ในขณะที่true
กลายเป็นคล้ายกับ1
แต่ไม่มีหมายเลขอื่น ๆ :
true == 1 // true
true == 2 // false
มีเหตุผลอะไรบ้างที่จะนำมาtrue
รวมกับ1
? เป็นที่ยอมรับ1
มีความโดดเด่น แต่ก็เป็น-1
เช่นนั้น ผมเองไม่เห็นเหตุผลใด ๆ ที่จะแปลงไปtrue
1
และมันยิ่งแย่ลงไปอีก:
true + 2 // 3
true - 1 // 0
ดังนั้นtrue
จะถูกแปลงเป็น1
ตัวเลขทั้งหมด! มันเป็นตรรกะหรือไม่ มันใช้งานง่าย? คำตอบที่เหลือคือการออกกำลังกาย;)
แต่สิ่งที่เกี่ยวกับเรื่องนี้:
1 && true // true
2 && true // true
บูลีนเพียงx
กับx && true
ความเป็นอยู่คือtrue
x = true
ซึ่งพิสูจน์ได้ว่าทั้งสอง1
และ2
(และหมายเลขอื่น ๆ0
) แปลงเป็นtrue
! สิ่งที่มันแสดงให้เห็นว่าการแปลงของเราล้มเหลวคุณสมบัติที่สำคัญอื่น - เป็นbijection หมายความว่าเอนทิตีที่แตกต่างกันสองรายการสามารถแปลงเป็นเอนทิตีเดียวกันได้ ซึ่งโดยตัวของมันเองไม่จำเป็นต้องเป็นปัญหาใหญ่ ปัญหาใหญ่เกิดขึ้นเมื่อเราใช้การแปลงนี้เพื่ออธิบายความสัมพันธ์ของ "ความเหมือน" หรือ "ความเท่าเทียมกันหลวม" ของสิ่งที่เราต้องการเรียกมันว่า แต่สิ่งหนึ่งที่ชัดเจน - มันจะไม่เป็นความสัมพันธ์ที่เท่าเทียมกันและมันจะไม่อธิบายอย่างสังหรณ์ใจผ่านคลาสที่เท่าเทียมกัน
แต่เราทำได้ดีกว่าได้ไหม
อย่างน้อยทางคณิตศาสตร์ - ใช่แน่นอน! ความสัมพันธ์ที่เท่าเทียมกันง่ายในหมู่ booleans และตัวเลขจะสร้างมีเพียงfalse
และ0
อยู่ในระดับเดียวกัน ดังนั้นfalse == 0
จะเป็นเพียงความเท่าเทียมกันหลวมที่ไม่น่ารำคาญ
แล้วสตริงล่ะ?
เราสามารถตัดสตริงจาก whitespaces ที่จุดเริ่มต้นและจุดสิ้นสุดเพื่อแปลงเป็นตัวเลขได้เช่นกันเราสามารถละเว้นเลขศูนย์หน้าได้:
' 000 ' == 0 // true
' 0010 ' == 10 // true
ดังนั้นเราจึงได้กฎง่าย ๆ สำหรับสตริง - ตัดช่องว่างและเลขศูนย์ด้านหน้า เราจะได้จำนวนหรือสตริงว่างซึ่งในกรณีนี้เราแปลงเป็นตัวเลขหรือศูนย์ หรือเราไม่ได้ตัวเลขซึ่งในกรณีนี้เราไม่ได้รับการแปลงและดังนั้นจึงไม่มีความสัมพันธ์ใหม่
วิธีนี้เราสามารถได้รับความสัมพันธ์ที่สมบูรณ์แบบจริง ๆ ในชุดบูลีน, ตัวเลขและสตริงทั้งหมด! ยกเว้นว่า ... ผู้ออกแบบ JavaScript มีความคิดเห็นอื่นอย่างชัดเจน:
' ' == '' // false
ดังนั้นทั้งสองสายที่ทั้งคู่เปลี่ยนไปใน0
ทันทีก็ไม่เหมือนกัน! ทำไมหรือเพราะอะไร ตามกฎแล้วสตริงจะเท่ากันอย่างแม่นยำเมื่อพวกเขาเท่ากันอย่างเคร่งครัด! ไม่เพียง แต่กฏนี้จะทำลายทรานสวิฟท์ตามที่เราเห็น แต่ยังเป็นกฎซ้ำซ้อน! จุดประสงค์ในการสร้างโอเปอเรเตอร์อื่น==
เพื่อให้เหมือนกันกับโอเปอเรเตอร์อื่นอย่างเคร่งครัด===
คืออะไร
ข้อสรุป
ตัวดำเนินการความเสมอภาคแบบหลวม==
อาจมีประโยชน์มากถ้ามันปฏิบัติตามกฎทางคณิตศาสตร์พื้นฐานบางอย่าง แต่เนื่องจากมันไม่ได้น่าเศร้า