Yanıtlar:
~
Bir olan bit düzeyinde operatör kendi işlenen tüm bitlerini çevirir.
Örneğin, numaranız IEEE 754 şamandıra (JavaScript'in sayıları nasıl ele 1
aldığı) ikili temsili olurdu ...
0011 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
Yani ~
işlenenini 32 bit tam sayıya dönüştürür (JavaScript'teki bitsel operatörler bunu yapar) ...
0000 0000 0000 0000 0000 0000 0000 0001
Negatif bir sayı olsaydı, 2'nin tamamlayıcısı içinde saklanırdı: tüm bitleri tersine çevir ve 1'i ekle.
... ve sonra tüm parçalarını çevirir ...
1111 1111 1111 1111 1111 1111 1111 1110
Peki bunun faydası ne? Ne zaman kullanılabilir?
Birkaç kullanım alanı vardır. Düşük seviyeli şeyler yazıyorsanız, kullanışlı. Uygulamanızı profillendirdiyseniz ve bir darboğaz bulduysanız, bitsel hileler ( daha büyük bir çantada olası bir araç olarak) kullanılarak daha performans gösterilebilir .
Ayrıca (genellikle) belirsiz hile açmak için indexOf()
s' bulundu içine dönüş değeri truthy (yapmada ise bulunamadı olarak falsy ) ve insanlar genellikle Katlama tarafından 32 bite numaralarını kesiliyor (ve ondalık yeri bırakarak onun yan etkisi için kullanmak, Math.floor()
pozitif sayılarla aynı şekilde etkili ).
Diyorum belirsiz bunun için kullanılıyor hemen belli gibi değil çünkü. Genel olarak, kodunuzun okuyan diğer kullanıcılarla net bir şekilde iletişim kurmasını istersiniz. Kullanırken ~
olabilir serin bakmak , genellikle kendi iyiliği için çok zeki. :)
O JavaScript sahip olduğunu da artık daha az alakalı Array.prototype.includes()
ve String.prototype.includes()
. Bunlar bir boolean değeri döndürür. Hedef platformlarınız destekliyorsa, bunu bir dizede veya dizide bir değerin olup olmadığını test etmek için tercih etmelisiniz.
value = value || default
JavaScript'te de, ne zaman kullanabileceğinizi ve kullanamayacağınızı bildiğiniz sürece yaygın ve geçerli bir deyimdir.
v = t ? a : b;
. Ben var v; if (t} { v = a; } else { v = b; }
genellikle 5+ satır kırık daha net ve aynı zamanda var v = b; if (t) { v = a; }
genellikle 4 + satır daha net buluyorum . Ama ? :
ikinci veya üçüncü yolu tercih edecek operatörlere aşina olmayan birçok insan tanıyorum . İlkinin daha okunabilir olduğunu düşünüyorum. Genel prensibe katılıyorum, kodu netleştirin, kesmek kullanmayın. Sanırım ~v.indexOf('...')
öğrendikten sonra çok net görüyorum .
~
deyimsel. teknik olarak dil spesifikasyonunun bir parçasıdır , ancak genel kullanımda dilin bir parçası değildir .
Bir indexOf()
ifadeden önce kullanmak, doğrudan döndürülen sayısal dizin yerine doğru / yanlış bir sonuç verir.
Dönüş değeri ise -1
, o zaman ~-1
olduğu 0
çünkü -1
her 1 bit bir dizedir. Sıfıra eşit veya sıfırdan büyük herhangi bir değer sıfırdan farklı bir sonuç verecektir. Böylece,
if (~someString.indexOf(something)) {
}
if
"someString" içinde "bir şey" olduğunda kodun çalışmasına neden olur . .indexOf()
Doğrudan bir boolean olarak kullanmaya çalışırsanız , bu işe yaramaz çünkü bazen sıfır döndürür ("bir şey" dizenin başında olduğunda).
Tabii ki, bu da işe yarıyor:
if (someString.indexOf(something) >= 0) {
}
ve çok daha az gizemli.
Bazen bunu da görürsünüz:
var i = ~~something;
~
İşleci bu şekilde iki kez kullanmak, bir dizeyi 32 bit tam sayıya dönüştürmenin hızlı bir yoludur. Birincisi ~
dönüşümü yapar ve ikincisi ~
bitleri geri çevirir. Elbette, operatör bir sayıya dönüştürülemeyen bir şeye uygulanırsa, NaN
sonuç olarak elde edersiniz . ( düzenle - aslında ~
ilk uygulanan ikinci, ama fikri anladınız.)
~
Tamsayılarla yapıldığında yavaş yavaş olumsuzlamak istemeyenler için eşittir -(x + 1)
.
0
varlık false
ve sıfır olmayan varlık geleneği true
en azından 70'lerde C'ye ve muhtemelen diğer çağdaş sistem programlama dillerine kadar uzanır. Muhtemelen donanımın çalışma şeklinden kaynaklanmaktadır; birçok CPU bir işlemden sonra sıfır biti ayarlar ve test etmek için karşılık gelen bir dal talimatına sahiptir.
| 0
, bu durumda tek bir işlem olacaktır.
~~
aynı şekilde yorumlamamak için çalışma zamanına güvenemeyiz .
~
Olduğu Bit DEĞİL Operatör , ~x
kabaca aynıdır -(x+1)
. Bunu anlamak daha kolay. Yani:
~2; // -(2+1) ==> -3
Düşünün -(x+1)
. -1
üretmek için bu işlemi yapabilir 0
.
Başka bir deyişle, ~
bir dizi sayı değeriyle birlikte kullanıldığında, yalnızca girdi değeri için bir yanlış (zorlama-den- false
arası 0
) -1
değeri oluşur, aksi takdirde başka bir doğruluk değeri üretir.
Bildiğimiz gibi -1
, genellikle sentinel değeri denir . Başarı ve başarısızlık için >= 0
değer döndüren birçok işlev için kullanılır-1
C dilinde. indexOf()
JavaScript ile aynı dönüş değeri kuralı .
Bu şekilde başka bir dizede bir alt dizenin varlığını / yokluğunu kontrol etmek yaygındır
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
}
Ancak, ~
aşağıdaki gibi yapmak daha kolay olurdu
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)
Bir if ifadesinde görüp görmediğime ikinci kez bakarım . Tilde bana Javascript'in 0 tabanlı doğasını telafi etmek için ne yaptığını söylüyor. Ayrıca, daha az parantez okumak için daha iyi
if (a.indexOf("Ba") > -1) {// found} //true
, tilde örneklerinden biraz daha uzun olmasına rağmen, verdiğiniz iki örnekten ve yeni programcılar için var opinion = !~-1 ? 'more' : 'less'
anlaşılabilir olandan daha az olan kullanarak daha az yazabilirsiniz .
~indexOf(item)
oldukça sık ortaya çıkıyor ve buradaki cevaplar harika, ama belki de bazı insanlar bunu nasıl kullanacağını bilmeli ve teoriyi "atlamalı":
if (~list.indexOf(item)) {
// item in list
} else {
// item *not* in list
}
++
ve --
"aşırı hileyi teşvik ediyorlar" ve yine de bir şekilde ~
hayatta kaldılar (gölgelerde gizleniyorlar) github.com/airbnb/javascript/issues/540
list.indexOf(item) >= 0
veya ... > -1
javascript sıfır temelli olduğundan ve bu sorunu en baştan ele almayı seçmedi. Dahası, sadece görüş (Airbnb'lerle aynı), javascriptte anlamlı bir şey yapan herkes bilir ++
ve --
daha az yaygın olsa da, anlam çıkarılabilir.
++
ve --
bir süre map
sonra forEach
vb ~
. Bir şeyi yasaklamak için CIS101 hiçbir anlam ifade etmiyor.
Bir sonuçtan doğruluk değeri oluşturmak için yaklaşık işareti kullanmayı düşünenlerindexOf
için, daha açıktır ve bunun yerine includes
yöntemiString
kullanmak için daha az sihir vardır .
'hello world'.includes('hello') //=> true
'hello world'.includes('kittens') //=> false
Bunun ES 2015'ten itibaren yeni bir standart yöntem olduğunu ve eski tarayıcılarda çalışmadığını unutmayın. Bunun önemli olduğu durumlarda, String.prototype.incfind çoklu dolguyu kullanmayı düşünün .
Bu özellik aynı sözdizimini kullanan diziler için de kullanılabilir :
['apples', 'oranges', 'cherries'].includes('apples') //=> true
['apples', 'oranges', 'cherries'].includes('unicorns') //=> false
Daha eski tarayıcı desteğine ihtiyacınız varsa Array.prototype.incfits çoklu dolgusunu burada bulabilirsiniz .