JavaScript melacak leluhurnya kembali ke C, dan C tidak memiliki operator XOR yang logis. Terutama karena itu tidak berguna. Bitwise XOR sangat berguna, tetapi dalam semua tahun pemrograman saya, saya tidak pernah membutuhkan XOR logis.
Jika Anda memiliki dua variabel boolean, Anda dapat meniru XOR dengan:
if (a != b)
Dengan dua variabel arbitrer yang dapat Anda gunakan !
untuk memaksa mereka ke nilai boolean dan kemudian menggunakan trik yang sama:
if (!a != !b)
Itu cukup tidak jelas dan tentu saja layak mendapatkan komentar. Memang, Anda bahkan bisa menggunakan operator XOR bitwise pada titik ini, meskipun ini akan terlalu pintar untuk seleraku:
if (!a ^ !b)
!=
adalah bahwa Anda tidak dapat melakukan hal yang samaa ^= b
, karenaa !== b
hanya operator ketimpangan yang ketat .Javascript memiliki operator XOR bitwise: ^
Anda dapat menggunakannya dengan booleans dan itu akan memberikan hasilnya sebagai 0 atau 1 (yang dapat Anda konversi kembali ke boolean, misalnya
result = !!(op1 ^ op2)
). Tapi seperti kata John, itu setara denganresult = (op1 != op2)
, yang lebih jelas.sumber
true^true
adalah 0, danfalse^true
1.||
dan&&
dapat digunakan sebagai operator logis pada non-boolean (mis.5 || 7
mengembalikan nilai"bob" && null
kebenaran , mengembalikan nilai falsey) tetapi^
tidak bisa. Misalnya,5 ^ 7
sama dengan 2, yang benar.(true ^ false) !== true
yang membuatnya menjengkelkan dengan perpustakaan yang membutuhkan boolean yang sebenarnyaa ^= true
untuk beralih boolean dan gagal pada beberapa mesin seperti telepon.Tidak ada operator boolean logis nyata di Javascript (meskipun
!
datang cukup dekat). Operator logis hanya akan mengambiltrue
ataufalse
sebagai operan dan hanya akan mengembalikantrue
ataufalse
.Dalam Javascript
&&
dan||
ambil semua jenis operan dan kembalikan semua jenis hasil lucu (apa pun yang Anda masukkan ke dalamnya).Juga operator logis harus selalu memperhitungkan nilai kedua operan.
Dalam Javascript
&&
dan||
mengambil jalan pintas malas dan tidak mengevaluasi operan kedua dalam kasus-kasus tertentu dan dengan demikian mengabaikan efek samping. Perilaku ini tidak mungkin dibuat ulang dengan xor logis.a() && b()
mengevaluasia()
dan mengembalikan hasilnya jika itu palsu. Kalau tidak, ia mengevaluasib()
dan mengembalikan hasilnya. Oleh karena itu hasil yang dikembalikan adalah benar jika kedua hasil benar, dan sebaliknya sebaliknya.a() || b()
mengevaluasia()
dan mengembalikan hasilnya jika itu benar. Kalau tidak, ia mengevaluasib()
dan mengembalikan hasilnya. Oleh karena itu hasil yang dikembalikan adalah falsy jika kedua hasil falsy, dan sebaliknya sebaliknya.Jadi ide umumnya adalah mengevaluasi operan kiri terlebih dahulu. Operan yang tepat hanya akan dievaluasi jika perlu. Dan nilai terakhir adalah hasilnya. Hasil ini bisa apa saja. Benda, angka, string .. terserah!
Ini memungkinkan untuk menulis hal-hal seperti
atau
Tetapi nilai kebenaran dari hasil ini juga dapat digunakan untuk memutuskan apakah operator logis "nyata" akan mengembalikan benar atau salah.
Ini memungkinkan untuk menulis hal-hal seperti
atau
Tetapi operator x "logis" (
^^
) harus selalu mengevaluasi kedua operan. Ini membuatnya berbeda dengan operator "logis" lainnya yang mengevaluasi operan kedua hanya jika perlu. Saya pikir ini sebabnya tidak ada "logis" xor dalam Javascript, untuk menghindari kebingungan.Jadi apa yang harus terjadi jika kedua operan itu palsu? Keduanya bisa dikembalikan. Tetapi hanya satu yang bisa dikembalikan. Yang mana? Yang pertama? Atau yang kedua? Intuisi saya memberi tahu saya untuk mengembalikan operator pertama tetapi biasanya "logis" mengevaluasi dari kiri ke kanan dan mengembalikan nilai yang terakhir dievaluasi. Atau mungkin array yang mengandung kedua nilai?
Dan jika satu operan adalah kebenaran dan operan lainnya adalah palsu, sebuah xor harus mengembalikan yang benar. Atau mungkin array yang berisi yang benar, agar kompatibel dengan case sebelumnya?
Dan akhirnya, apa yang harus terjadi jika kedua operan itu benar? Anda akan mengharapkan sesuatu yang palsu. Tetapi tidak ada hasil palsu. Jadi operasi seharusnya tidak mengembalikan apa pun. Jadi mungkin
undefined
atau .. array kosong? Tapi array kosong masih benar.Mengambil pendekatan array Anda akan berakhir dengan kondisi seperti
if ((a ^^ b).length !== 1) {
. Sangat membingungkan.sumber
XOR dari dua boolean hanyalah apakah mereka berbeda, oleh karena itu:
sumber
Konversikan nilai menjadi bentuk Boolean kemudian ambil bitor XOR. Ini akan membantu dengan nilai-nilai non-boolean juga.
sumber
Terselubung ke boolean dan kemudian melakukan xor seperti -
sumber
!!a ^ !!b
setara dengan!a ^ !b
. Argumen bisa dibuat yang lebih mudah dibaca.ada ... semacam:
atau lebih mudah dibaca:
Mengapa? tidak tahu
karena pengembang javascript berpikir itu tidak perlu karena dapat diekspresikan oleh operator lain yang sudah diimplementasikan.
Anda bisa saja memiliki gon dengan nand dan hanya itu, Anda dapat mengesankan setiap operasi logis yang mungkin dari itu.
Saya pribadi berpikir itu memiliki alasan historis yang mendorong dari bahasa sintaksis berbasis-c, di mana setahu saya xor tidak ada atau paling tidak jarang.
sumber
Ya, lakukan saja yang berikut ini. Dengan asumsi bahwa Anda berurusan dengan boolean A dan B, maka nilai XOR B dapat dihitung dalam JavaScript menggunakan berikut ini
Baris sebelumnya juga setara dengan yang berikut ini
Secara pribadi, saya lebih suka xor1 karena saya harus mengetikkan lebih sedikit karakter. Saya percaya bahwa xor1 juga lebih cepat. Itu hanya melakukan dua perhitungan. xor2 sedang melakukan tiga perhitungan.
Penjelasan Visual ... Baca tabel di bawah ini (di mana 0 berarti false dan 1 berarti benar) dan bandingkan kolom 3 dan 5.
! (A === B):
Nikmati.
sumber
var xor1 = !(a === b);
sama denganvar xor1 = a !== b;
!(2 === 3)
adalahtrue
, tetapi2
dan3
yang truthy sehingga2 XOR 3
harusfalse
.Periksa:
Anda dapat menirunya seperti ini:
sumber
Bagaimana mengubah hasil int ke bool dengan negasi ganda? Tidak begitu cantik, tetapi sangat kompak.
sumber
B = ((!state1)!==(!state2))
B =!!(!state1 ^ !state2);
Juga, mengapa begitu banyak kurung?B = !state1 !== !state2;
Atau Anda bahkan dapat menghapus negasi:B = state1 !== state2;
state1 !== state2
, maka Anda tidak perlu melakukan casting di sana, karena!==
operator logis, bukan bitwise.12 !== 4
benar'xy' !== true
juga benar. Jika Anda akan menggunakan!=
alih-alih!==
, maka Anda harus melakukan casting.!==
dan!=
selalu boolean ... tidak yakin apa perbedaan yang Anda buat seharusnya ada, itu sama sekali bukan masalahnya. Masalahnya adalah bahwa operator XOR yang kita inginkan benar-benar ekspresi(Boolean(state1) !== Boolean(state2))
. Untuk boolean, "xy", 12, 4 dantrue
semuanya adalah nilai yang benar, dan harus dikonversi menjaditrue
. jadi("xy" XOR true)
seharusnyafalse
, tetapi("xy" !== true)
sebaliknyatrue
, seperti yang Anda tunjukkan. Jadi!==
atau!=
sama dengan "logis XOR" jika dan hanya jika Anda mengonversi argumen mereka menjadi boolean sebelum mendaftar.Dalam fungsi xor di atas akan menghasilkan hasil SIMILAR karena xor logis tidak persis xor logis, artinya akan menghasilkan "false untuk nilai yang sama" dan "true untuk nilai yang berbeda" dengan pencocokan jenis data sebagai pertimbangan.
Fungsi XOR ini akan bekerja sebagai xor aktual atau operator logis , berarti itu akan menghasilkan sesuai benar atau salah dengan nilai-nilai yang lewat adalah truthy atau falsy . Gunakan sesuai dengan kebutuhan Anda
sumber
(!!x) === (!!y)
. Perbedaannya adalah gips ke boolean.'' === 0
itu salah, sementaraxnor('', 0)
itu benar.Dalam Skrip (+ perubahan ke nilai numerik):
Begitu:
sumber
!!(false ^ true)
berfungsi baik dengan boolean. Dalam naskah, + diperlukan untuk membuatnya valid!!(+false ^ +true)
.cond1 xor cond2
setara dengancond1 + cond 2 == 1
:Inilah buktinya:
sumber
Alasan tidak ada XOR logis (^^) adalah karena tidak seperti && dan || itu tidak memberikan keuntungan malas-logika. Itu adalah keadaan kedua ekspresi di kanan dan kiri harus dievaluasi.
sumber
Berikut ini solusi alternatif yang berfungsi dengan 2+ variabel dan memberikan hitungan sebagai bonus.
Berikut adalah solusi yang lebih umum untuk mensimulasikan XOR logis untuk nilai kebenaran / falsey, sama seperti jika Anda memiliki operator dalam pernyataan IF standar:
Alasan saya suka ini, adalah karena ia juga menjawab "Berapa banyak dari variabel-variabel ini yang benar?", Jadi saya biasanya menyimpannya terlebih dahulu.
Dan bagi mereka yang menginginkan perilaku cek ketat boolean-TRUE, hanya:
Jika Anda tidak peduli dengan penghitungan, atau jika Anda peduli tentang kinerja optimal: maka gunakan bitor xor pada nilai yang dipaksakan ke boolean, untuk solusi yang benar / salah:
sumber
Hai saya menemukan solusi ini, untuk membuat dan XOR pada JavaScript dan TypeScript.
sumber
Coba ini pendek dan mudah dimengerti
Ini akan bekerja untuk semua tipe data
sumber
true == someboolean
itu tidak perlu, jadi sungguh, apa yang Anda lakukan adalah membungkus ketat yang tidak sama dengan fungsi.