var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
? 'value'
: 'innerHTML'
Saya melihatnya dalam sebuah jawaban, dan saya belum pernah melihatnya sebelumnya.
Apa artinya?
var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
? 'value'
: 'innerHTML'
Saya melihatnya dalam sebuah jawaban, dan saya belum pernah melihatnya sebelumnya.
Apa artinya?
Jawaban:
~
adalah operator bitwise yang membalik semua bit di operan.
Misalnya, jika nomor Anda adalah 1
, representasi biner dari float IEEE 754 (bagaimana JavaScript memperlakukan angka) akan ...
0011 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
Jadi ~
konversikan operan ke integer 32 bit (operator bitwise dalam JavaScript melakukan itu) ...
0000 0000 0000 0000 0000 0000 0000 0001
Jika itu adalah angka negatif, itu akan disimpan dalam komplemen 2's: membalikkan semua bit dan menambahkan 1.
... dan kemudian membalik semua bagiannya ...
1111 1111 1111 1111 1111 1111 1111 1110
Jadi apa gunanya itu? Kapan seseorang bisa menggunakannya?
Ini memiliki beberapa kegunaan. Jika Anda menulis hal-hal tingkat rendah, ini berguna. Jika Anda membuat profil aplikasi Anda dan menemukan hambatan, itu bisa dibuat lebih berkinerja dengan menggunakan trik bitwise (sebagai salah satu alat yang mungkin dalam tas yang jauh lebih besar).
Ini juga merupakan (umumnya) tidak jelas trik untuk mengubah indexOf()
's ditemukan nilai kembali ke truthy (sementara membuat tidak ditemukan sebagai falsy ) dan orang sering menggunakannya untuk efek samping dari truncating nomor ke 32 bit (dan menjatuhkan tempat desimal sebesar dua kali lipat itu, efektif sama dengan Math.floor()
untuk angka positif).
Saya katakan tidak jelas karena tidak jelas apa gunanya. Secara umum, Anda ingin kode Anda berkomunikasi dengan jelas kepada orang lain yang membacanya. Meskipun menggunakan ~
mungkin terlihat keren , umumnya terlalu pintar untuk kebaikannya sendiri. :)
Ini juga kurang relevan sekarang karena JavaScript telah Array.prototype.includes()
dan String.prototype.includes()
. Ini mengembalikan nilai boolean. Jika platform target Anda mendukungnya, Anda harus memilih ini untuk menguji keberadaan nilai dalam string atau array.
value = value || default
dalam JavaScript adalah idiom umum dan valid selama Anda tahu kapan Anda bisa dan tidak bisa menggunakannya.
v = t ? a : b;
. Saya menemukan bahwa jauh lebih jelas daripada var v; if (t} { v = a; } else { v = b; }
biasanya menembus 5+ baris dan juga lebih jelas daripada var v = b; if (t) { v = a; }
biasanya 4+ baris. Tapi saya tahu banyak orang yang tidak terbiasa dengan ? :
operator yang lebih suka cara kedua atau ketiga. Saya menemukan yang pertama lebih mudah dibaca. Saya setuju dengan prinsip umum, jelaskan kodenya, jangan gunakan peretasan. Saya kira saya hanya melihat ~v.indexOf('...')
dengan sangat jelas setelah saya mempelajarinya.
~
idiomatik. itu secara teknis bagian dari spesifikasi bahasa , tapi itu bukan bagian dari bahasa yang umum digunakan .
Menggunakannya sebelum indexOf()
ekspresi secara efektif memberi Anda hasil yang benar / salah, bukan indeks numerik yang langsung dikembalikan.
Jika nilai kembali -1
, maka ~-1
adalah 0
karena -1
adalah string dari semua 1 bit. Nilai apa pun yang lebih besar dari atau sama dengan nol akan memberikan hasil yang tidak nol. Jadi,
if (~someString.indexOf(something)) {
}
akan menyebabkan if
kode berjalan ketika "sesuatu" ada di "someString". Jika Anda mencoba menggunakan .indexOf()
sebagai boolean secara langsung, maka itu tidak akan berhasil karena kadang-kadang ia mengembalikan nol (ketika "sesuatu" berada di awal string).
Tentu saja, ini juga berfungsi:
if (someString.indexOf(something) >= 0) {
}
dan itu jauh kurang misterius.
Terkadang Anda juga akan melihat ini:
var i = ~~something;
Menggunakan ~
operator dua kali seperti itu adalah cara cepat untuk mengubah string ke integer 32-bit. Yang pertama ~
melakukan konversi, dan yang kedua ~
membalik bit kembali. Tentu saja jika operator diterapkan pada sesuatu yang tidak dapat dikonversi ke angka, Anda dapatkan NaN
hasilnya. ( sunting - sebenarnya ini yang kedua ~
diterapkan pertama kali, tetapi Anda mendapatkan idenya.)
~
ketika dilakukan pada bilangan bulat sama dengan -(x + 1)
.
0
keberadaan false
dan bukan-nol yang true
berasal dari masa lalu, setidaknya sampai C di tahun 70-an dan mungkin banyak bahasa pemrograman sistem kontemporer lainnya. Mungkin berasal dari cara perangkat keras bekerja; banyak CPU menetapkan sedikit nol setelah operasi, dan memiliki instruksi cabang yang sesuai untuk mengujinya.
| 0
, dalam hal ini hanya satu operasi.
~~
dengan cara yang persis sama.
Ini ~
adalah Bitwise NOT Operator , ~x
kira-kira sama dengan -(x+1)
. Lebih mudah dimengerti, semacam. Begitu:
~2; // -(2+1) ==> -3
Pertimbangkan -(x+1)
. -1
dapat melakukan operasi itu untuk menghasilkan a 0
.
Dengan kata lain, ~
digunakan dengan kisaran nilai angka akan menghasilkan nilai falsy (memaksa false
dari 0
) hanya untuk nilai -1
input, jika tidak, nilai kebenaran lainnya.
Seperti yang kita ketahui, -1
biasanya disebut nilai sentinel . Hal ini digunakan untuk banyak fungsi yang mengembalikan >= 0
nilai-nilai untuk sukses dan -1
untuk kegagalan dalam bahasa C. Yang mana nilai aturan pengembalian yang sama indexOf()
dalam JavaScript.
Adalah umum untuk memeriksa ada / tidaknya substring di string lain dengan cara ini
var a = "Hello Baby";
if (a.indexOf("Ba") >= 0) {
// found it
}
if (a.indexOf("Ba") != -1) {
// found it
}
if (a.indexOf("aB") < 0) {
// not found
}
if (a.indexOf( "aB" ) == -1) {
// not found
}
Namun, akan lebih mudah untuk melakukannya ~
seperti di bawah ini
var a = "Hello Baby";
~a.indexOf("Ba"); // -7 -> truthy
if (~a.indexOf("Ba")) { // true
// found it
}
~a.indexOf("aB"); // 0 -> falsy
!~a.indexOf("aB"); // true
if (!~a.indexOf( "aB" )) { // true
// not found
}
-(x+1)
jika saya melihatnya dalam pernyataan if. Tilde memberi tahu saya apa yang dilakukan untuk mengimbangi sifat berbasis-Javascript. Juga, semakin sedikit tanda kurung semakin baik untuk membaca
if (a.indexOf("Ba") > -1) {// found} //true
yang, meskipun sedikit lebih panjang dari contoh tilde, jauh lebih sedikit dari dua contoh yang Anda berikan dan untuk programmer baru dapat var opinion = !~-1 ? 'more' : 'less'
dimengerti.
~indexOf(item)
muncul cukup sering, dan jawabannya di sini luar biasa, tetapi mungkin beberapa orang hanya perlu tahu cara menggunakannya dan "melewatkan" teorinya:
if (~list.indexOf(item)) {
// item in list
} else {
// item *not* in list
}
++
dan --
karena mereka "mendorong trickiness berlebihan" dan entah bagaimana ~
bertahan (bersembunyi di bayang-bayang) github.com/airbnb/javascript/issues/540
list.indexOf(item) >= 0
atau ... > -1
karena javascript berbasis nol dan tidak memilih untuk mengatasi ini sejak awal. Lebih jauh, hanya opini (sama seperti Airbnb), siapa pun yang melakukan sesuatu yang bermakna dalam javascript tahu ++
, dan meskipun --
kurang umum, artinya dapat disimpulkan.
++
dan --
dalam beberapa waktu karena metode primitif seperti map
, forEach
dll. Maksud saya adalah lebih banyak tentang mengapa mereka juga tidak menganggap ~
terlalu rumit ketika standar apa pun yang digunakan termasuk operator kenaikan dan penurunan. Untuk melarang sesuatu sehingga CIS101 tidak masuk akal.
Bagi mereka yang mempertimbangkan menggunakan trik tilde untuk menciptakan nilai kebenaran dari suatu indexOf
hasil, itu lebih eksplisit dan memiliki lebih sedikit keajaiban untuk alih-alih menggunakan includes
metode iniString
.
'hello world'.includes('hello') //=> true
'hello world'.includes('kittens') //=> false
Perhatikan bahwa ini adalah metode standar baru pada ES 2015 sehingga tidak akan berfungsi pada browser lama. Dalam kasus di mana itu penting, pertimbangkan untuk menggunakan String.prototype.include polyfill .
Fitur ini juga tersedia untuk array menggunakan sintaks yang sama :
['apples', 'oranges', 'cherries'].includes('apples') //=> true
['apples', 'oranges', 'cherries'].includes('unicorns') //=> false
Berikut adalah Array.prototype.include polyfill jika Anda memerlukan dukungan browser yang lebih lama.