Jika Anda membaca komentar di inArray
halaman jQuery di sini , ada deklarasi yang menarik:
!!~jQuery.inArray(elm, arr)
Sekarang, saya yakin tanda seru ganda akan mengubah hasil menjadi tipe boolean
, dengan nilai true
. Yang tidak saya mengerti adalah apa gunanya ~
operator tilde ( ) dalam semua ini?
var arr = ["one", "two", "three"];
if (jQuery.inArray("one", arr) > -1) { alert("Found"); }
Refactoring if
pernyataan:
if (!!~jQuery.inArray("one", arr)) { alert("Found"); }
Kerusakan:
jQuery.inArray("one", arr) // 0
~jQuery.inArray("one", arr) // -1 (why?)
!~jQuery.inArray("one", arr) // false
!!~jQuery.inArray("one", arr) // true
Saya juga memperhatikan bahwa jika saya meletakkan tilde di depan, hasilnya adalah -2
.
~!!~jQuery.inArray("one", arr) // -2
Saya tidak mengerti tujuan tilde di sini. Bisakah seseorang menjelaskan atau mengarahkan saya ke sumber daya?
javascript
jquery
operators
bitwise-operators
pengguna717236
sumber
sumber
~jQuery.inArray()
sebenarnya sangat berguna - bahkan mungkin alasan yang sangat bagus mengapa fungsi pencarian kembali-1
gagal (satu-satunya nilai yang keduanya saling melengkapi salah). Setelah Anda melihat dan memahami triknya, saya merasa ini lebih mudah dibaca daripada!= -1
.!!~
untuk apa-apa .if (x != -1)
danif (~x)
bagi saya, yang pertama sebenarnya mengungkapkan apa yang ingin Anda lakukan. Yang terakhir mengungkapkan Anda ingin melakukan sesuatu yang lain sepenuhnya ("tolong ubah 64-bit Number saya menjadi integer 32-bit, dan periksa apakah bitwise NOT dari integer itu benar"), di mana Anda kebetulan mendapatkan hasil yang diinginkan dalam hal ini satu kasus.>= 0
mungkin tidak cukup leet , jadi yang lebih samar!!~
digunakan.Jawaban:
Operator tilde sebenarnya bukan bagian dari jQuery - ini bukan operator bitwise di JavaScript itu sendiri.
Lihat The Great Mystery of the Tilde (~) .
Anda mendapatkan angka-angka aneh dalam percobaan Anda karena Anda melakukan operasi logis bitwise pada integer (yang, sejauh yang saya tahu, dapat disimpan sebagai pelengkap dua atau sesuatu seperti itu ...)
Komplemen dua menjelaskan bagaimana merepresentasikan bilangan dalam biner. Saya pikir saya benar.
sumber
Ada alasan spesifik yang terkadang Anda lihat
~
diterapkan di depan$.inArray
.Pada dasarnya,
adalah cara yang lebih singkat untuk dilakukan
$.inArray
mengembalikan indeks item dalam larik jika argumen pertama ditemukan, dan mengembalikan -1 jika tidak ditemukan. Ini berarti bahwa jika Anda mencari boolean "apakah nilai ini dalam array?", Anda tidak dapat melakukan perbandingan boolean, karena -1 adalah nilai yang benar, dan saat $ .inArray mengembalikan 0 (nilai yang salah ), artinya sebenarnya ditemukan di elemen pertama dari array.Menerapkan
~
operator bitwise menyebabkan-1
menjadi0
, dan menyebabkan 0 menjadi `-1. Jadi, tidak menemukan nilai dalam larik dan menerapkan bitwise NOT akan menghasilkan nilai yang salah (0), dan semua nilai lainnya akan mengembalikan angka bukan-0, dan akan mewakili hasil yang benar.Dan itu akan bekerja sebagaimana mestinya.
sumber
!!~expr
mengevaluasifalse
saatexpr
ini-1
sebaliknyatrue
.Sama seperti
expr != -1
, hanya rusak *Ini berfungsi karena operasi bitwise JavaScript mengubah operan menjadi integer bertanda 32-bit dalam format komplemen dua. Dengan demikian
!!~-1
dievaluasi sebagai berikut:Nilai selain
-1
akan memiliki setidaknya satu bit disetel ke nol; membalikkannya akan menciptakan nilai kebenaran; menerapkan!
operator dua kali ke nilai yang benar mengembalikan boolean true.Ketika digunakan dengan
.indexOf()
dan kami hanya ingin memeriksa apakah hasilnya-1
atau tidak:*
!!~8589934591
Dievaluasi ke false jadi inikekejiantidak dapat digunakan secara andal untuk menguji-1
.sumber
~foo.indexOf(bar)
, ini bukan penghematan yang signifikan pada karakter atau kinerja, tetapi ini adalah singkatan yang relatif umum dengan cara yangfoo = foo || {}
sama.!!
.>= 0
tidak memiliki perilaku yang sama dengan!!~
.!== -1
lebih dekat.~foo.indexOf(bar)
adalah singkatan umum untuk diwakilifoo.contains(bar)
karenacontains
fungsinya tidak ada.Biasanya cast ke boolean tidak diperlukan karena konsep JavaScript tentang nilai "salah". Dalam hal ini digunakan untuk memaksa keluaran fungsi menjadi
true
ataufalse
.sumber
jQuery.inArray()
kembali-1
untuk "tidak ditemukan", yang komplemennya (~
) adalah0
. Jadi,~jQuery.inArray()
mengembalikan nilai salah (0
) untuk "tidak ditemukan", dan nilai kebenaran (bilangan bulat negatif) untuk "ditemukan".!!
kemudian akan memformalkan falsy / truthy menjadi booleanfalse
/true
. Jadi,!!~jQuery.inArray()
akan diberikantrue
untuk "ditemukan" danfalse
untuk "tidak ditemukan".sumber
Untuk
~
semua 4 byteint
sama dengan rumus ini-(N+1)
BEGITU
sumber
~2147483648 != -(2147483648 + 1)
.The
~
operator adalah operator bitwise pelengkap. Hasil integer dariinArray()
adalah -1, jika elemen tidak ditemukan, atau beberapa integer non-negatif. Pelengkap bitwise -1 (direpresentasikan dalam biner karena semua 1 bit) adalah nol. Pelengkap bitwise dari bilangan bulat non-negatif selalu bukan nol.Jadi,
!!~i
akan menjaditrue
saat bilangan bulat "i" adalah bilangan bulat non-negatif, danfalse
bila "i" tepat -1.Perhatikan bahwa
~
selalu memaksa operannya menjadi integer; yaitu, ini memaksa nilai floating point non-integer menjadi integer, serta nilai non-numerik.sumber
Tilde TIDAK bitwise - itu membalikkan setiap bit nilai. Sebagai pedoman umum, jika Anda menggunakan
~
angka, tandanya akan dibalik, kemudian 1 akan dikurangi.Jadi, jika Anda melakukannya
~0
, Anda mendapatkan -1 (0 terbalik adalah -0, dikurangi 1 adalah -1).Ini pada dasarnya adalah cara yang rumit dan sangat mikro-dioptimalkan untuk mendapatkan nilai yang selalu Boolean.
sumber
Anda benar: Kode ini akan kembali
false
ketikaindexOf
panggilan kembali -1; sebaliknyatrue
.Seperti yang Anda katakan, akan jauh lebih masuk akal menggunakan sesuatu seperti
sumber
.js
. Karena itu, mereka dapat menggunakan>=0
daripada!==-1
- tidak ada byte tambahan untuk dikirim dan masih lebih mudah dibaca daripada versi bit-twiddling.> -1
bahkan lebih mudah dibaca, tapi itu mungkin sangat subjektif.Itu
~
Operator adalah bitwise TIDAK operator. Artinya, ia mengambil bilangan dalam bentuk biner dan mengubah semua nol menjadi satu dan satu menjadi nol.Misalnya, angka 0 dalam biner adalah
0000000
, sedangkan -1 adalah11111111
. Demikian juga, 100000001
dalam biner, sedangkan -2 adalah11111110
.sumber
Dugaan saya adalah bahwa itu ada karena itu beberapa karakter lebih pendek (yang selalu dicari oleh penulis perpustakaan). Ini juga menggunakan operasi yang hanya mengambil beberapa siklus mesin saat dikompilasi ke dalam kode asli (sebagai lawan dari perbandingan dengan angka.)
Saya setuju dengan jawaban lain bahwa ini berlebihan tetapi mungkin masuk akal dalam loop yang ketat (memerlukan estimasi perolehan kinerja, meskipun, jika tidak, mungkin berubah menjadi pengoptimalan prematur.)
sumber
Saya berasumsi, karena ini adalah operasi bitwise, ini adalah cara tercepat (murah secara komputasi) untuk memeriksa apakah jalur muncul di modifiedPaths.
sumber
Seperti
(~(-1)) === 0
, jadi:sumber