Mengapa (0 <5 <3) mengembalikan true?

348

Saya bermain-main di jsfiddle.net dan saya ingin tahu mengapa ini kembali benar?

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

Begitu juga ini:

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

Tetapi ini tidak:

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

Apakah kekhasan ini berguna?

punkrockbuddyholly
sumber
12
Apakah Anda kenal wtfjs.com ?
Harmen
1
Ha! Tidak, saya belum pernah melihat itu sebelumnya.
punkrockbuddyholly
Ah, kegembiraan konversi tipe implisit.
Jörg W Mittag
4
Pernah bermanfaat? Mungkin untuk kebingungan. :-)
Icode4food
Mengapa? Juga, segala sesuatu berguna jika Anda hanya dapat menemukan keadaan yang mengharuskannya. Benar, yang satu ini lebih jarang dituntut daripada banyak yang lain, tetapi ada kalanya, sedikit dan jauh di antara mereka, di mana itu mungkin alat yang tepat untuk pekerjaan itu.
temporary_user_name

Jawaban:

440

Urutan operasi menyebabkan (0 < 5 < 3)ditafsirkan dalam javascript sebagai ((0 < 5) < 3)yang menghasilkan (true < 3)dan true dihitung sebagai 1, menyebabkannya kembali benar.

Ini juga mengapa (0 < 5 < 1)mengembalikan false, (0 < 5)mengembalikan true, yang ditafsirkan sebagai 1, menghasilkan (1 < 1).

Alan Geleynse
sumber
158
Dan karena JavaScript BUKAN Python. :-)
rsenna
1
Anda menjawab sementara saya mengedit pertanyaan saya untuk menambahkan if(0 < 5 < 1) == false. Semua sudah jelas sekarang, terima kasih :)
punkrockbuddyholly
28
Tepatnya, Python adalah satu-satunya bahasa yang saya tahu yang memperlakukan sintaksis ini karena ((0 < 5) && (5 < 3)), mungkin ada yang lain tapi saya tidak tahu mereka.
Alan Geleynse
18
@Lan: Mathematica adalah contoh lain.
Joren
2
IMHO JavaScript harus meningkatkan TypeError ketika mencoba membandingkan boolean dengan angka, karena itu tidak masuk akal.
Michał Perłakowski
63

Dugaan saya adalah karena 0 < 5itu benar, dan true < 3mendapatkan 1 < 3yang benar.

CaffGeek
sumber
7
Tidak ada casting di sini. Pemain adalah operator, yang digunakan programmer untuk secara eksplisit memeriksa suatu jenis. Ini adalah konversi implisit dari boolean ke integer.
erickson
4
@erickson, sungguh ... apakah kita PERLU digantung di semantik di sini?
CaffGeek
2
Jangan khawatir tentang erickson. Saya juga menyalahgunakan kata semantik. :)
Mateen Ulhaq
9
Bagaimanapun, istilah yang benar adalah paksaan . Dan ya, erickson sebagian salah dengan kepastian mutlaknya. Paksaan dalam hal apapun semacam pemeran juga jika biasanya (tapi itu hanya konvensi) Anda menggunakan kata "pemeran" untuk mengekspresikan konversi jenis eksplisit. Jenis konversi == Jenis casting.
Jack
1
Para sofis sepanjang jalan ... Jawabannya bagus 'singkatnya';)
Arman McHitarian
21

mungkin karena truedianggap 1demikian

0 < 5 < 3  -->  true < 3 -->  1 < 3  --> true
Mendongkrak
sumber
17

Karena true < 3, karenatrue == 1

Harmen
sumber
10

Adapun pertanyaan Anda apakah kekhasan ini pernah berguna: Saya kira mungkin ada beberapa kasus di mana itu akan berguna (jika kode kental adalah apa yang Anda cari), tetapi dengan mengandalkan itu akan (kemungkinan besar) sangat mengurangi pemahaman kode Anda.

Ini seperti menggunakan post / pre increment / decrement sebagai bagian dari ekspresi yang lebih besar. Bisakah Anda menentukan apa hasil kode ini sekilas?

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

Catatan: dengan kode ini, Anda kadang-kadang bahkan bisa mendapatkan hasil berbeda tergantung pada bahasa dan kompiler

Merupakan ide bagus untuk membuat hidup Anda mudah bagi diri Anda sendiri dan orang berikutnya yang akan membaca kode Anda. Tuliskan dengan jelas apa yang sebenarnya Anda inginkan terjadi daripada mengandalkan efek samping seperti konversi boolean secara implisit.

Zach Johnson
sumber
Karena penasaran, apakah result18?
punkrockbuddyholly
5
@MrMisterMan: Saya tidak yakin tentang Javascript, tetapi dalam Java dan C # evaluasi dijamin akan dibiarkan ke kanan, dan hasilnya memang 18. Dalam beberapa bahasa, seperti C dan C ++, tidak ada jaminan itu akan dievaluasi dari kiri ke kanan, dan Anda mungkin berakhir dengan hasil yang berbeda tergantung pada optimasi yang ditambahkan oleh kompiler Anda.
Zach Johnson
9

Jawaban untuk bagian kedua dari pertanyaan, "apakah kekhasan ini pernah berguna?" mungkin tidak, seperti dicatat oleh jawaban sebelumnya, jika itu memang kekhasan bahasa (Javascript) yang benar dilemparkan ke 1, tetapi bahwa programmer tidak dalam tampilan umum 1 dan benar (dan 0 dan salah) sebagai hal yang sama.

Namun jika Anda memiliki model mental 1 menjadi benar dan 0 menjadi salah, maka itu mengarah ke semua jenis teknik boolean bagus yang sangat berguna, kuat, dan langsung. Misalnya, Anda bisa menambah penghitung secara langsung dengan hasil A> 100, yang akan menambah penghitung jika A lebih besar dari 100. Teknik ini mungkin dipandang sebagai kekhasan atau tipuan di Jawa, tetapi dalam array atau bahasa fungsional mungkin idiom.

Contoh klasik dalam bahasa array APL adalah menghitung jumlah item dalam array yang (katakanlah) lebih besar dari 100:

+/A>100

Di mana jika A adalah array 5 item 107 22 256 110 3 maka:

A>100

menghasilkan 5 item array boolean:

1 0 1 1 0

dan menjumlahkan hasil boolean ini:

+/1 0 1 1 0

menghasilkan jawaban akhir:

3

Pertanyaan ini adalah contoh sempurna di mana teknik ini akan sangat berguna, terutama jika masalahnya digeneralisasi untuk menentukan apakah n dari nilai m boolean benar.

Periksa apakah setidaknya dua dari tiga boolean benar

PAUL Mansour
sumber
7

Itu mudah.

(0 < 5 < 3)

Mulai dengan kiri ke kanan sehingga mengevaluasi 0 pertama <5. Apakah itu benar? Iya. Karena TRUE = 1, itu mengevaluasi 1 <3. Karena 1 kurang dari 3 jadi itu benar.

Sekarang dengan ini

 (0 < 5 < 1)

Apakah 0 kurang dari 5? Iya. Jadi buat itu BENAR yang juga berarti 1. Sekarang dengan fakta itu dalam pikiran, ia mengevaluasi ke (1 <1). Apakah 1 kurang dari 1? Tidak, karena itu salah. Itu harus sama.

netrox
sumber
4

apakah itu mengevaluasi 0 <5 yang akan mengembalikan 1 untuk true ketika 1 <3 yang benar?

C # ingin Anda melakukan ini "Operator '<' tidak dapat diterapkan ke operan tipe 'bool' dan 'int'"

David
sumber
Terkadang saya ketinggalan kekakuan C # dalam bahasa dinamis.
Arman McHitarian
4

Saya mengalami ini beberapa saat yang lalu di Obj-C dan sangat bingung karenanya. Saya mendapatkan hasil yang saya inginkan dengan melakukan sesuatu seperti ini:

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

Tentu saja itu salah sehingga Anda tidak akan mendapatkan peringatan "benar" itu. Senang saya membaca ini, saya sekarang tahu mengapa.

Hippocrates
sumber
4

Selain python, CoffeeScript adalah bahasa lain yang mendukung perbandingan berantai, sehingga 3 < x < 10akan dikonversi ke (3 < x && x < 10)dalam vanilla JS

Hippocrates
sumber
3
0 < 5 < 3 
==> ( ( 0 < 5 ) < 3 )
==> true < 3
==> 1 < 3
==> true
truease.com
sumber
1

Operan boolean ketika dioperasikan melalui operator matematika mengembalikan nomor. untuk memeriksa ini kita lakukan

true + 1  which gives you 2.

Jadi 0 < 5, boolean yang dikembalikan (benar) dioperasikan dengan operator matematika (<) akan mengembalikan angka. Jadi itu mendidih ke 1 <3 yang kembalitrue

Rajkamal Subramanian
sumber
1

karena 0 kurang dari 5 maka itu mengembalikan true, dan secara default true adalah segala sesuatu termasuk dan dapat dievaluasi ke 1 yang masih kurang dari 3 yang lagi mengembalikan true

ndoty
sumber
0

coba frasa hasil Anda sebagai Angka ()

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

atau coba ini:

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

Saya googled ini karena saya mendapatkan (3 >= 20) //returning truedan saya kira javascript mencoba memeriksa 3sebagai boolean karena saya mendapatkan nilai ini dari elm.getAttribute();fungsi yang console.log();mencetak dalam bentuk String.

SwiftNinjaPro
sumber