Jeśli czytasz komentarze na jQuery inArray
stronie tutaj , jest interesująca deklaracja:
!!~jQuery.inArray(elm, arr)
Teraz uważam, że podwójny wykrzyknik przekonwertuje wynik na typ boolean
o wartości true
. Nie rozumiem, jakie jest zastosowanie w tym ~
wszystkim operatora tyldy ( )?
var arr = ["one", "two", "three"];
if (jQuery.inArray("one", arr) > -1) { alert("Found"); }
Refaktoryzacja if
instrukcji:
if (!!~jQuery.inArray("one", arr)) { alert("Found"); }
Awaria:
jQuery.inArray("one", arr) // 0
~jQuery.inArray("one", arr) // -1 (why?)
!~jQuery.inArray("one", arr) // false
!!~jQuery.inArray("one", arr) // true
Zauważyłem również, że jeśli umieszczę tyldę z przodu, wynik jest -2
.
~!!~jQuery.inArray("one", arr) // -2
Nie rozumiem tutaj celu tyldy. Czy ktoś może to wyjaśnić lub wskazać mi źródło informacji?
javascript
jquery
operators
bitwise-operators
user717236
źródło
źródło
~jQuery.inArray()
jest w rzeczywistości bardzo przydatny - być może nawet bardzo dobry powód, dla którego funkcje wyszukiwania zwracają-1
błąd (jedyna wartość, której uzupełnienie do dwóch jest fałszywe). Kiedy już zobaczysz i zrozumiesz tę sztuczkę, czuję, że jest ona jeszcze bardziej czytelna niż!= -1
.!!~
do niczego .if (x != -1)
iif (~x)
dla mnie polega na tym, że to pierwsze faktycznie wyraża to, co zamierzasz zrobić. To ostatnie wyraża chęć zrobienia czegoś zupełnie innego ("proszę przekonwertować moją 64-bitową liczbę na 32-bitową liczbę całkowitą i sprawdzić, czy bitowe NIE tej liczby jest prawdziwe"), gdzie po prostu uzyskasz pożądany wynik w tym jeden przypadek.>= 0
prawdopodobnie nie był wystarczająco jasny , więc!!~
użyto bardziej tajemniczego .Odpowiedzi:
Operator tyldy w rzeczywistości nie jest częścią jQuery - jest operatorem bitowym NOT w samym JavaScript.
Zobacz The Great Mystery of the Tilde (~) .
Otrzymujesz dziwne liczby w swoich eksperymentach, ponieważ wykonujesz bitową operację logiczną na liczbie całkowitej (która, o ile wiem, może być przechowywana jako uzupełnienie do dwóch lub coś w tym rodzaju ...)
Dopełnienie do dwóch wyjaśnia, jak przedstawić liczbę w systemie binarnym. Myślę, że miałem rację.
źródło
Istnieje konkretny powód, dla którego czasami zobaczysz
~
zastosowany przed$.inArray
.Gruntownie,
to krótszy sposób
$.inArray
zwraca indeks pozycji w tablicy, jeśli zostanie znaleziony pierwszy argument, i zwraca -1, jeśli nie zostanie znaleziony. Oznacza to, że jeśli szukasz wartości logicznej „czy ta wartość jest w tablicy?”, Nie możesz wykonać porównania boolowskiego, ponieważ -1 jest prawdziwą wartością, a kiedy $ .inArray zwraca 0 (wartość fałszywą ), to znaczy, że faktycznie znajduje się w pierwszym elemencie tablicy.Zastosowanie
~
operatora bitowego powoduje,-1
że staje się0
i powoduje, że 0 staje się `` -1. Tak więc, nie znalezienie wartości w tablicy i zastosowanie bitowego NIE skutkuje błędną wartością (0), a wszystkie inne wartości zwrócą liczby inne niż 0 i będą reprezentować prawdziwy wynik.I będzie działać zgodnie z przeznaczeniem.
źródło
!!~expr
ocenia,false
kiedyexpr
jest-1
inaczejtrue
.To samo co
expr != -1
, tylko zepsute *Działa, ponieważ operacje bitowe JavaScript konwertują operandy na 32-bitowe liczby całkowite ze znakiem w formacie dopełnienia do dwóch. Tak więc
!!~-1
jest oceniany w następujący sposób:Wartość inna niż
-1
będzie miała co najmniej jeden bit ustawiony na zero; odwrócenie go stworzy prawdziwą wartość; zastosowanie!
dwukrotne operatora do prawdziwej wartości zwraca wartość logiczną prawda.W przypadku użycia z
.indexOf()
i chcemy tylko sprawdzić, czy wynik jest,-1
czy nie:*
!!~8589934591
zwraca wartość false, więc towstrętnie można wiarygodnie użyć do przeprowadzenia testów-1
.źródło
~foo.indexOf(bar)
, nie ma to znaczących oszczędności na postaci lub wydajności, ale jest to stosunkowo powszechny skrót w ten sam sposóbfoo = foo || {}
.!!
.>= 0
nie zachowuje się tak samo jak!!~
.!== -1
jest bliżej.~foo.indexOf(bar)
jest popularnym skrótem do reprezentacji,foo.contains(bar)
ponieważcontains
funkcja nie istnieje.Zazwyczaj rzutowanie na wartości logiczne jest niepotrzebne ze względu na koncepcję „fałszywych” wartości w JavaScript. W tym przypadku służy do wymuszenia wartości wyjściowej funkcji na
true
orfalse
.źródło
jQuery.inArray()
zwraca-1
„nie znaleziono”, którego uzupełnieniem (~
) jest0
. Tak więc~jQuery.inArray()
zwraca fałszywą wartość (0
) dla „nie znaleziono” i prawdziwą wartość (ujemną liczbę całkowitą) dla „znalezionego”.!!
następnie sformalizuje fałsz / prawda do prawdziwej wartości logicznejfalse
/true
. Więc!!~jQuery.inArray()
podatrue
jako „znaleziony” ifalse
„nie znaleziony”.źródło
Wartość
~
dla wszystkich 4 bajtówint
jest równa tej formule-(N+1)
WIĘC
źródło
~2147483648 != -(2147483648 + 1)
.~
Operator jest operatorem bitowym uzupełnieniem. Wynik liczby całkowitej zinArray()
wynosi -1, gdy element nie został znaleziony, lub nieujemną liczbą całkowitą. Bitowe uzupełnienie -1 (reprezentowane binarnie jako wszystkie 1 bity) wynosi zero. Uzupełnienie bitowe dowolnej nieujemnej liczby całkowitej jest zawsze niezerowe.Tak więc
!!~i
będzie,true
gdy liczba całkowita „i” jest nieujemną liczbą całkowitą, afalse
gdy „i” jest równe dokładnie -1.Zauważ, że
~
zawsze przekształca swój operand do liczby całkowitej; to znaczy wymusza niecałkowite wartości zmiennoprzecinkowe na liczby całkowite, jak również na wartości nieliczbowe.źródło
Tilda jest bitowa NIE - odwraca każdy bit wartości. Zgodnie z ogólną zasadą, jeśli użyjesz
~
liczby, jej znak zostanie odwrócony, a następnie odejmie się 1.Tak więc, kiedy to robisz
~0
, otrzymasz -1 (0 odwrócone to -0, odejmij 1 to -1).Zasadniczo jest to skomplikowany, super-mikro-zoptymalizowany sposób uzyskiwania wartości, która zawsze jest logiczna.
źródło
Masz rację: ten kod zwróci,
false
gdyindexOf
wywołanie zwróci -1; Inaczejtrue
.Jak mówisz, znacznie rozsądniej byłoby użyć czegoś takiego
źródło
.js
. Powiedziawszy to, mogliby użyć>=0
zamiast!==-1
- żadnych dodatkowych bajtów do wysłania i nadal bardziej czytelnej niż wersja bitowa.> -1
jest to jeszcze bardziej czytelne, ale to prawdopodobnie bardzo subiektywne.Plik
~
Operator jest NIE bitowe operatora. Oznacza to, że przyjmuje liczbę w postaci binarnej i zamienia wszystkie zera w jedynki, a jedynki w zera.Na przykład liczba 0 w systemie binarnym to
0000000
, a -1 to11111111
. Podobnie 1 jest00000001
binarny, a -2 jest11111110
.źródło
Domyślam się, że jest, ponieważ jest o kilka znaków krótszy (których autorzy biblioteki zawsze szukają). Używa również operacji, które zajmują tylko kilka cykli maszynowych po skompilowaniu do kodu natywnego (w przeciwieństwie do porównania z liczbą).
Zgadzam się z inną odpowiedzią, że to przesada, ale może mieć sens w wąskiej pętli (wymaga jednak oszacowania wzrostu wydajności, w przeciwnym razie może się okazać przedwczesną optymalizacją).
źródło
Zakładam, że ponieważ jest to operacja bitowa, jest to najszybszy (tani obliczeniowo) sposób sprawdzenia, czy ścieżka pojawia się w modifiedPaths.
źródło
Tak
(~(-1)) === 0
więc:źródło