Mam dla Was lekkostrawny temat. Przyznajcie się, kiedy ostatni raz używaliście tyldę? (Chwila namysłu.) No właśnie. To nie jest najbardziej popularny znaczek w Javascripcie. Coś obiło się o uszy na studiach. Czasami nam miga taki klawisz przed oczami. Wciska się zamiast wykrzyknika. A coś konkretniej? Przypomnijmy sobie, o jakie buty chodzi z tą tyldą.
Tylda ~
Wiemy, że każdą liczbę można zapisać w systemie binarnym (tak, chodzi o zera i jedynki). Operator negacji bitowej – tylda ~
– służy do negacji poszczególnych bitów w liczbie.
Przykład (źródło):
var n = 10; // 00000000000000000000000000001010
n = ~n; // 11111111111111111111111111110101
Rozumiem, że dla codziennego użytku taka definicja niewiele nam daje. Dlatego można też powiedzieć inaczej – tylda konwertuje liczby całkowite do wartości -(N+1). O, to już jakiś konkret!
~(2) // => -3
~(-6) // => 5
A co się stanie, jeśli dajemy tyldzie liczbę nie-całkowitą? Albo stringa? Albo booleana? Po prostu JS najpierw spróbuje sobie to coś przekonwertować do liczby całkowitej. Dopiero późnej dokona negacji. Uwaga, jeśli dana wartość nie może być przekonwertowana do liczby, dostaniesz 0
. Jeśli podajesz tyldzie liczbę z ułamkiem, zostanie ona zamieniona na liczbę całkowitą powstałą po zwykłym ucięciu ułamka.
~(5.7) // => -6
~(false) // => ~(0) => -1
~(true) // => ~(1) => -2
~("7") // => -8
~("happy xmas") // => ~(0) => -1
~(["and", "happy", "new", "year"]) // => ~(0) => -1
~({}) // => ~(0) => -1
~(["5"]) // => -6
~([5,6]) // => ~(0) => -1
Podwójna tylda ~~
Podwójna tylda to analogicznie podwójna operacja negacji bitowej.
-(-(N+1)+1) = -(-N-1+1) = N
No popatrzcie krok po kroku, że to działa.
~(2) // => -3
~(-3) // => 2
Operator zwraca liczbę całkowitą, która powstaje po ucięciu ułamka z danej wartości. Bardzo często podwójna tylda jest więc używana po prostu do zaokrąglania liczb.
~~5.5 // => 5
Możecie się spotkać ze stwierdzeniem, że podwójna tylda to szybszy zamiennik Math.floor()
.
Cóż, nie do końca.
Po pierwsze podwójna tylda jest szybsza na jednych przeglądarkach, a na drugich już nie. Nie wspominając o tym, że owe różnice są naprawdę mało znaczące.
Po drugie – działanie podwójnej tyldy i .floor()
trochę się różni. Podwójna tylda kasuje wszystko po prawej stronie od ułamka dziesiętnego. A to ma ogromne znaczenie dla ujemnych liczb. Pod tym względem tyldzie jest bliżej do Math.trunc()
, które również bezwzględnie ucina ułamki. Poza tym podwójna tylda zawsze zwraca liczbę, nigdy nie zwróci NaN
. Jak już wspomniałam, jeśli dana wartość nie może być przekonwertowana do liczby, dostaniesz 0
.
~~5.7 // => 5
Math.floor(5.7) // => 5
~~(-5.7) // => -5
Math.floor(-5.7) // => -6
Generalnie ludzie nie lubią podwójnej tyldy. Ze względów oczywistych – jest mało czytelna. Zaokrąglenie liczby to tylko efekt uboczny podwójnej negacji bitowej. Taka sytuacja zmusza programistę do wielkiego trudu myślenia „co autor miał na myśli”. A myślenie nie jest w modzie.
Podsumowanie
Tylda służy do negacji bitów liczby całkowitej, a dwie tyldy to podwójna negacja. Mówiłam, że dziś będzie lekkostrawnie