ทำไม (0 <5 <3) ถึงกลับจริง


348

ฉันกำลังเล่นอยู่ใน jsfiddle.net และฉันอยากรู้ว่าทำไมสิ่งนี้ถึงได้ผลตอบแทนจริง?

if(0 < 5 < 3) {
    alert("True");
}

ดังนั้นสิ่งนี้:

if(0 < 5 < 2) {
    alert("True");
}

แต่นี่ไม่ใช่:

if(0 < 5 < 1) {
    alert("True");
}

การเล่นโวหารนี้มีประโยชน์เคย?


12
คุณรู้จักwtfjs.comหรือไม่
Harmen

1
ฮา! ไม่ฉันไม่เคยเห็นมาก่อน
punkrockbuddyholly

อ้าความสุขของการแปลงประเภทโดยนัย
Jörg W Mittag

4
เคยมีประโยชน์ไหม อาจเป็นไปได้สำหรับ obfuscation :-)
Icode4food

ทำไม? นอกจากนี้สิ่งใดมีประโยชน์หากคุณสามารถค้นหาสถานการณ์ที่จำเป็นต้องใช้เท่านั้น จริงอยู่คนนี้มักจะต้องการน้อยกว่าคนอื่น ๆ หลายคน แต่มีบางครั้งน้อยและไกลระหว่างพวกเขาอาจจะเป็นที่ซึ่งมันอาจเป็นเครื่องมือสำหรับงาน
temporary_user_name

คำตอบ:


440

ลำดับของการดำเนินการทำให้เกิด(0 < 5 < 3)การตีความในจาวาสคริปต์((0 < 5) < 3)ที่สร้างขึ้น(true < 3)และความจริงถูกนับเป็น 1 ทำให้มันกลับเป็นจริง

และนี่ก็เป็นเหตุผลว่าทำไม(0 < 5 < 1)ผลตอบแทนเท็จ(0 < 5)ผลตอบแทนที่แท้จริงซึ่งถูกตีความว่าเป็นผลในการ1(1 < 1)


158
และเนื่องจาก JavaScript ไม่ใช่ Python :-)
rsenna

1
if(0 < 5 < 1) == falseคุณตอบว่าในขณะที่ผมแก้ไขคำถามของฉันที่จะเพิ่ม ทุกอย่างชัดเจนแล้วขอบคุณ :)
punkrockbuddyholly

28
Python เป็นภาษาเดียวที่ฉันรู้จักที่ใช้กับไวยากรณ์นี้เนื่องจาก((0 < 5) && (5 < 3))อาจมีคนอื่น แต่ฉันไม่รู้พวกเขา
Alan Geleynse

18
@Alan: Mathematica เป็นอีกตัวอย่างหนึ่ง
Joren

2
IMHO JavaScript ควรเพิ่ม TypeError เมื่อพยายามเปรียบเทียบบูลีนกับตัวเลขเพราะไม่สมเหตุสมผล
MichałPerłakowski

63

ฉันเดาว่าเป็นเพราะ0 < 5จริงและtrue < 3ได้รับการโยน1 < 3ซึ่งเป็นเรื่องจริง


7
ไม่มีการคัดเลือกนักแสดงที่นี่ การส่งเป็นตัวดำเนินการซึ่งโปรแกรมเมอร์ใช้เพื่อตรวจสอบชนิดอย่างชัดเจน นี่คือการแปลงโดยนัยจากบูลีนเป็นจำนวนเต็ม
erickson

4
@erickson จริง ๆ ... พวกเราต้องการที่จะถูกแขวนอยู่กับความหมายที่นี่?
CaffGeek

2
ไม่ต้องกังวลกับ erickson ฉันใช้ความหมายในทางที่ผิดเช่นกัน :)
Mateen Ulhaq

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

1
Sophists ตลอดทาง ... คำตอบคือ 'laconically' nice ต่อไป;)
Arman McHitarian



10

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

มันเหมือนกับการใช้การเพิ่ม / ลดโพสต์ / ก่อนเป็นส่วนหนึ่งของการแสดงออกที่ใหญ่กว่า คุณสามารถระบุได้ว่าผลลัพธ์ของโค้ดนี้คืออะไร?

int x = 5;
int result = ++x + x++ + --x;

หมายเหตุ: ด้วยรหัสนี้บางครั้งคุณสามารถได้ผลลัพธ์ที่แตกต่างกันขึ้นอยู่กับภาษาและคอมไพเลอร์

เป็นความคิดที่ดีที่จะทำให้ชีวิตง่ายขึ้นสำหรับตัวคุณเองและคนต่อไปที่จะอ่านรหัสของคุณ เขียนสิ่งที่คุณต้องการให้เกิดขึ้นอย่างชัดเจนแล้วอาศัยผลข้างเคียงเช่นการแปลงโดยนัยของบูลีน


จากความอยากรู้result18 หรือไม่?
punkrockbuddyholly

5
@MrMisterMan: ฉันไม่แน่ใจเกี่ยวกับ Javascript แต่ใน Java และ C # การประเมินจะได้รับการรับรองจากซ้ายไปขวาและผลที่ได้คือ 18 ในบางภาษาเช่น C และ C ++ ไม่มีการรับประกันว่าจะเป็น ประเมินจากซ้ายไปขวาและคุณอาจได้ผลลัพธ์ที่แตกต่างกันขึ้นอยู่กับการปรับแต่งที่เพิ่มโดยคอมไพเลอร์ของคุณ
Zach Johnson

9

คำตอบในส่วนที่สองของคำถาม "การเล่นโวหารนี้มีประโยชน์หรือไม่" อาจจะไม่ดังที่บันทึกไว้โดยคำตอบก่อนหน้าถ้าเป็นจริงของภาษา (จาวาสคริปต์) ที่จริงถูกโยนเป็น 1 แต่โปรแกรมเมอร์ไม่ได้อยู่ในมุมมองทั่วไป 1 และจริง (และ 0 และเท็จ) เป็น สิ่งเดียวกัน

หากคุณมีแบบจำลองทางจิตว่า 1 เป็นจริงและ 0 เป็นเท็จมันจะนำไปสู่เทคนิคบูลีนที่น่าสนใจทุกประเภทที่มีประโยชน์มากมีประสิทธิภาพและตรงไปตรงมา ตัวอย่างเช่นคุณสามารถเพิ่มตัวนับโดยตรงด้วยผลลัพธ์ของ A> 100 ซึ่งจะเพิ่มตัวนับหาก A มากกว่า 100 เทคนิคนี้อาจถูกมองว่าเป็นมุมแหลมหรือหลอกลวงใน Java แต่ในอาร์เรย์หรือภาษาที่ใช้งานได้ อาจเป็นสำนวน

ตัวอย่างคลาสสิกในภาษาอาเรย์ APL คือการนับจำนวนรายการในอาเรย์ที่ (พูด) มากกว่า 100:

+/A>100

โดยที่ถ้า A คืออาร์เรย์ 5 รายการ 107 22 256 110 3 ให้ทำดังนี้

A>100

ผลผลิตอาร์เรย์แบบบูล 5 รายการ:

1 0 1 1 0

และรวมผลบูลีนนี้:

+/1 0 1 1 0

ให้ผลลัพธ์คำตอบสุดท้าย:

3

คำถามนี้เป็นตัวอย่างที่สมบูรณ์แบบที่เทคนิคนี้จะมีประโยชน์มากโดยเฉพาะอย่างยิ่งถ้าปัญหาเป็นเรื่องทั่วไปเพื่อตรวจสอบว่าค่าบูลีน n ออกจาก m เป็นจริง

ตรวจสอบว่าอย่างน้อยสองในสามบูลีนเป็นจริง


7

ง่ายมาก

(0 < 5 < 3)

เริ่มจากซ้ายไปขวาเพื่อประเมิน 0 <5 แรกมันเป็นจริงหรือไม่? ใช่. ตั้งแต่ TRUE = 1 มันประเมิน 1 <3 เนื่องจาก 1 น้อยกว่า 3 ดังนั้นมันจึงเป็นจริง

ตอนนี้กับสิ่งนี้

 (0 < 5 < 1)

0 น้อยกว่า 5 หรือไม่ ใช่. ดังนั้นจงทำให้มันเป็นจริงซึ่งก็หมายถึง 1 ทีนี้เมื่อความจริงนั้นอยู่ในใจมันก็ประเมินค่าเป็น (1 <1) 1 น้อยกว่า 1 หรือไม่ ไม่เลยมันผิด มันจะต้องมีความเท่าเทียมกัน


4

มันประเมิน 0 <5 ซึ่งจะส่งกลับ 1 สำหรับจริงเมื่อ 1 <3 ซึ่งเป็นความจริง?

C # ต้องการให้คุณทำสิ่งนี้ "ตัวดำเนินการ '<' ไม่สามารถใช้กับตัวถูกดำเนินการประเภท 'bool' และ 'int'"


บางครั้งฉันพลาดข้อ จำกัด ของ C # ในภาษาไดนามิก
Arman McHitarian

4

เมื่อไม่นานมานี้ฉันวิ่งเข้าไปหาสิ่งนี้ใน Obj-C และรู้สึกงุนงงมาก ฉันได้ผลลัพธ์ที่ต้องการโดยทำสิ่งนี้:

if(0 < 5  && 5 < 3) {
alert("True");}

หลักสูตรใดเป็นเท็จดังนั้นคุณจะไม่ได้รับการแจ้งเตือน "จริง" ดีใจที่ฉันอ่านสิ่งนี้ตอนนี้ฉันรู้ว่าทำไม


4

นอกเหนือจากภาษาไพ ธ อนแล้ว CoffeeScript ยังเป็นอีกภาษาหนึ่งที่รองรับการเปรียบเทียบแบบมีสายซึ่ง3 < x < 10จะถูกแปลงเป็น(3 < x && x < 10)วานิลลา JS



1

ตัวถูกดำเนินการบูลีนเมื่อดำเนินการผ่านตัวดำเนินการทางคณิตศาสตร์ส่งกลับจำนวน เพื่อตรวจสอบสิ่งนี้เราทำ

true + 1  which gives you 2.

ดังนั้น0 < 5บูลีนที่ส่งคืน (จริง) ที่ดำเนินการกับตัวดำเนินการทางคณิตศาสตร์ (<) จะส่งคืนตัวเลข ดังนั้นมันจึงเดือดถึง 1 <3 ซึ่งกลับมาtrue


1

เพราะ 0 น้อยกว่า 5 แล้วส่งกลับค่าจริงและโดยค่าเริ่มต้นจริงคืออะไรรวมถึงและสามารถประเมินถึง 1 ซึ่งยังคงน้อยกว่า 3 ซึ่งผลตอบแทนจริงอีกครั้ง


0

ลองใช้ถ้อยคำผลลัพธ์ของคุณเป็นตัวเลข ()

if(Number(0) < Number(5) < Number(3)) {
    alert("True");
}

หรือลองสิ่งนี้:

if(Number(0) < Number(5) && Number(5) < Number(3)) {
    alert("True");
}

ฉันทำสิ่งนี้เพราะฉันเริ่ม(3 >= 20) //returning trueแล้วและฉันคิดว่าจาวาสคริปต์กำลังพยายามตรวจสอบ3ว่าเป็นบูลีนเพราะฉันได้รับค่านี้จากelm.getAttribute();ฟังก์ชั่นที่console.log();กำลังพิมพ์ในรูปแบบสตริง

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