How does!~ (not not tilde/bang bang tilde) zmienić wynik wywołania metody tablicy 'contains/included'?

Jeśli czytasz komentarze na stronie jQuery inArray tutaj , jest ciekawa deklaracja:

!!~jQuery.inArray(elm, arr) 

Teraz wierzę, że podwójny wykrzyknik przekonwertuje wynik na typ boolean, z wartością true. Nie rozumiem tylko, jaki jest w tym wszystkim użytek z operatora tylda (~)?

var arr = ["one", "two", "three"];
if (jQuery.inArray("one", arr) > -1) { alert("Found"); }

Refaktoryzacja wypowiedzi if:

if (!!~jQuery.inArray("one", arr)) { alert("Found"); }

Podział:

jQuery.inArray("one", arr)     // 0
~jQuery.inArray("one", arr)    // -1 (why?)
!~jQuery.inArray("one", arr)   // false
!!~jQuery.inArray("one", arr)  // true

Zauważyłem też, że jeśli postawię tyldę przed, wynikiem jest -2.

~!!~jQuery.inArray("one", arr) // -2
Nie rozumiem celu tyldy. Czy ktoś może to wyjaśnić lub wskazać mi źródło?
Author: Salman A, 2012-02-16

13 answers

Operator tyldy w rzeczywistości nie jest częścią jQuery w ogóle - jest operatorem bitowym Nie w samym JavaScript.

Zobacz Wielka tajemnica tyldy(~).

Dostajesz dziwne liczby w swoich eksperymentach, ponieważ wykonujesz bitowo logiczną operację na liczbie całkowitej (która, z tego co wiem, może być przechowywana jako dopełniacz dwóch lub coś w tym stylu...)

dopełnienie dwójki wyjaśnia, jak reprezentować liczbę w postaci binarnej. I chyba miałem rację.

 57
Author: p.g.l.hall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-03 20:41:56

Jest specyficzny powód, dla którego czasami widzisz ~ zastosowaną przed $.inArray.

Zasadniczo,

~$.inArray("foo", bar)

Jest krótszym sposobem na

$.inArray("foo", bar) !== -1

$.inArray zwraca indeks elementu w tablicy, jeżeli pierwszy argument zostanie znaleziony, a zwraca -1 jeżeli nie został znaleziony. Oznacza to, że jeśli szukasz wartości logicznej " is this value in the array?", nie można zrobić porównania boolowskiego, ponieważ -1 jest prawdziwą wartością, a gdy $.inArray zwraca 0 (wartość falsy), oznacza to, że jego faktycznie znaleziony w pierwszym elemencie tablicy.

Zastosowanie operatora bitowego ~ powoduje, że -1 staje się 0, A 0 staje się `-1. Tak więc, nie znalezienie wartości w tablicy i zastosowanie bitowego NOT skutkuje fałszywą wartością (0), a wszystkie inne wartości zwrócą liczby inne niż 0 i będą przedstawiać prawdziwy wynik.

if (~$.inArray("foo", ["foo",2,3])) {
    // Will run
}
I będzie działać zgodnie z przeznaczeniem.
 121
Author: Yahel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-01 00:11:19

!!~expr ewaluuje do false, Gdy expr jest -1, w przeciwnym razie true.
Jest taka sama jak expr != -1, tylko złamana*


Działa, ponieważ operacje bitowe JavaScript konwertują operandy na 32-bitowe liczby całkowite podpisane w formacie dopełniacza dwóch. Tak więc !!~-1 jest oceniane w następujący sposób:

   -1 = 1111 1111 1111 1111 1111 1111 1111 1111b // two's complement representation of -1
  ~-1 = 0000 0000 0000 0000 0000 0000 0000 0000b // ~ is bitwise not (invert all bits)
   !0 = true                                     // ! is logical not (true for falsy)
!true = false                                    // duh

Wartość inna niż -1 będzie miała co najmniej jeden bit ustawiony na zero; odwrócenie go spowoduje utworzenie wartości rzeczywistej; zastosowanie operatora ! dwa razy do wartości rzeczywistej Zwraca wartość logiczną prawda.

Gdy używamy z .indexOf() i chcemy tylko sprawdzić, czy wynik jest -1 czy nie:

!!~"abc".indexOf("d") // indexOf() returns -1, the expression evaluates to false
!!~"abc".indexOf("a") // indexOf() returns  0, the expression evaluates to true
!!~"abc".indexOf("b") // indexOf() returns  1, the expression evaluates to true

* !!~8589934591 ocenia NA false, więc to obrzydliwość nie może być niezawodnie użyte do testowania dla -1.

 105
Author: Salman A,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-05 19:11:46

~foo.indexOf(bar) jest powszechnym skrótem do reprezentowania foo.contains(bar), Ponieważ funkcja contains nie istnieje.

Typowo rzucanie na boolean jest niepotrzebne ze względu na koncepcję JavaScript "falsy" wartości. W tym przypadku służy do wymuszenia wyjścia funkcji na true lub false.

 33
Author: zzzzBov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-14 13:13:42

jQuery.inArray() zwraca -1 dla "not found" , którego dopełnieniem (~) jest 0. Tak więc ~jQuery.inArray() Zwraca wartość falsy (0) dla "not found" , a wartość true (ujemna liczba całkowita) dla"found". !! Następnie sformalizuje falsy / truthy do prawdziwego logicznego false/true. Tak więc !!~jQuery.inArray() da true dla "znalezione" i false Dla "Nie znalezione".

 18
Author: Amadan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-16 18:17:19

~ dla wszystkich 4 bajtów int jest równe tej Formule -(N+1)

Więc

~0   = -(0+1)   // -1
~35  = -(35+1)  // -36 
~-35 = -(-35+1) //34 
 13
Author: Mina Gabriel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-04 19:03:19

Operator ~ jest operatorem dopełniacza bitowego. Liczba całkowita wynik z inArray() jest albo -1, gdy element nie został znaleziony, albo jakaś nieujemna liczba całkowita. Dopełnienie bitowe -1 (reprezentowane w układzie binarnym jako Wszystkie 1 bity) wynosi zero. Bitowe dopełnienie dowolnej nieujemnej liczby całkowitej jest zawsze niezerowe.

Zatem !!~i będzie true gdy liczba całkowita " i "jest nieujemną liczbą całkowitą, a false Gdy" i " jest dokładnie -1.

Zauważ, że ~ zawsze wymusza swój operand na liczbę całkowitą; oznacza to, że wymusza nieliczbowe wartości zmiennoprzecinkowe na liczbę całkowitą, a także wartości nieliczbowe.

 10
Author: Pointy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-16 18:11:44

Tylda jest bitowa, a nie-odwraca każdy bit wartości. Ogólnie rzecz biorąc, jeśli użyjesz ~ Na liczbie, jej znak zostanie odwrócony, a następnie 1 zostanie odjęty.

Tak więc, kiedy robisz ~0, otrzymujesz -1 (0 odwrócone to -0, odjąć 1 to -1).

Jest to w zasadzie rozbudowany, super-mikro-zoptymalizowany sposób uzyskania wartości, która zawsze jest logiczna.
 10
Author: Joe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-16 18:12:52

Masz rację: Ten kod zwróci false gdy wywołanie indexOf zwróci -1; w przeciwnym razie true.

Jak mówisz, o wiele rozsądniej byłoby użyć czegoś takiego jak

return this.modifiedPaths.indexOf(path) !== -1;
 8
Author: LukeH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-14 11:34:58

Operator ~ jest operatorem bitowym NOT. Oznacza to, że przyjmuje liczbę w postaci binarnej i zamienia wszystkie zera w jedynki, a Jedynki w zera.

Na przykład liczba 0 w binarnym to 0000000, podczas gdy -1 to 11111111. Podobnie, 1 jest 00000001 w binarnym, podczas gdy -2 jest 11111110.

 6
Author: Frxstrem,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-16 18:14:36

Domyślam się, że jest tam, ponieważ jest o kilka znaków krótszy(których autorzy biblioteki są zawsze po). Używa również operacji, które zajmują tylko kilka cykli maszynowych po skompilowaniu do kodu natywnego (w przeciwieństwie do porównania do liczby.)

Zgadzam się z inną odpowiedzią, że to przesada, ale być może miałoby to sens w ciasnej pętli (wymaga jednak oszacowania przyrostu wydajności, w przeciwnym razie może okazać się przedwczesną optymalizacją.)

 3
Author: Alexander Pavlov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-14 11:25:54

Zakładam, że ponieważ jest to operacja bitowa, jest to najszybszy (tani obliczeniowo) sposób sprawdzenia, czy ścieżka pojawia się w zmodyfikowanych ścieżkach.

 2
Author: panos2point0,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-03 20:43:03

As (~(-1)) === 0, więc:

!!(~(-1)) === Boolean(~(-1)) === Boolean(0) === false
 1
Author: Engineer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-14 11:37:20