chevron-left chevron-right

Piotr Nalepa Frontend, architektura i AI

[JS] Prawda czy fałsz? Sztuczki z operatorami bitowymi i logicznymi w języku JavaScript

Ta wersja
blog.piotrnalepa.pl/2013/08/21/js-prawda-czy-falsz-sztuczki-z-operatorami-bitowymi-i-logicznymi-w-jezyku-javascript
Opublikowano
Autor
, Staff Software Engineer
Kategoria
JavaScript
Uwagi
Napisz do mnie · Napisz na X

Ten wpis ma 13 lat. Od tego czasu przeglądarki i narzędzia mogły się zmienić, więc zanim użyjesz kodu, sprawdź go z aktualną dokumentacją.

Tworząc aplikacje internetowe, czasami pojawia się potrzeba dokonania mikro optymalizacji w szybkości działania funkcji zaimplementowanych w aplikacjach. Dzięki nim, można osiągnąć lepszą wydajność aplikacji, a także większą stabilność działania. Jedną z możliwości jakie daje nam język JavaScript (i nie tylko) jest stosowanie operatorów bitowych i operatorów logicznych, które będą sprawdzały wartości zmiennych, odpowiednio je przekształcały do pożądanej przez nas formy czy też zastępowały pętle.

Sekcja 1Zaokrąglanie liczb za pomocą operatora NOT

W przypadku, gdy istnieje potrzeba zaokrąglania liczby w dół web developerzy stosują Math.floor(x), podczas gdy istnieją co najmniej 3 szybsze sposoby, aby osiągnąć ten sam efekt:

  • y = ~~x;,
  • y = x | 0;,
  • y = x >> 0;.

Wszystkie te 3 sposoby, są szybszymi zamiennikami popularnej metody do zaokrąglania w dół.

Sekcja 2Sprawdzanie czy liczba jest parzysta?

Tworząc różnego listingi lub budując tabelę z dynamicznie generowaną treścią (dodawanie/odejmowanie wierszy) bardzo często stosowane są klasy definiujące czy dany wiersz jest parzysty czy nieparzysty. W takich sytuacjach często są używane sprawdzenia czy kolejna liczba jest modułem z 2 - y = x % 2; i tutaj też jest zamiennik, który jest szybszy: y = (x & 1);. Zapis ten zwraca true, jeśli wartość jest nieparzysta.

Sekcja 3Zwracanie wartości typu boolowskiego/logicznego

Czasami web developerzy operują na zmiennych true/false i to jest w porządku. Lecz ze względu na to, że istnieją różne postaci typu fałszywego, takie jak:

  • false,
  • NaN,
  • undefined,
  • null,
  • '' (pusty string),
  • 0.

To nie mogą być one używane jako wartości właściwosci obiektów, które w założeniach przyjmują tylko wartości true lub false. W takich sytuacjach można wykorzystać zapis: y = !!x;. Gdyby x przyjął wartość undefined, to ten zapis zwróci wartość false, a w przypadku gdy wartość zmiennej będzie określona lub nie będzie typu fałszywego to będzie zwracała true, np. gdy zastosujemy taki zapis if (!!$('body').length) ....

Sekcja 4Działania warunkowe - if

Działania warunkowe w językach programowania są widokiem tak powszechnym, że z reguły nie sprawiają żadnych problemów z ich odczytaniem. Czasami można natknąć się na tajemnicze zapisy, które zachowują się jak warunki, ale na takie nie wyglądają. Są to skrócone zapisy warunku if lub inaczej wywołania warunkowe.

Przykład 1JavaScript
1
2
3
if (true) {
  wykonaj();
}

Standardowy warunku if można zastąpić zapisem: true && wykonaj();. Jest to zapis krótszy i może być wykorzystywany, gdy zależy będzie Ci zależało na maksymalnym zmniejszeniu wagi pliku.

Inne przykłady wykorzystania wywołań warunkowych są następujące:

Przykład 2JavaScript
1
2
3
if (!true) {
  wykonaj();
}

Powyższy zapis można zastąpić następującym kodem: true || wykonaj();. Czyli, jeśli wartość nie jest prawdziwa/nie istnieje to wykonaj funkcję.

Do tej pory wykonywaliśmy działania warunkowe, które wywołują się tylko w jednym przypadku. Lecz można też utworzyć skrótową wersję warunku if else za pomocą zapisu: x && wykonaj() || nieWykonuj();. Ten sam warunek można zapisać jeszcze inaczej: x ? wykonaj() : nieWykonuj();

Jednym z przykładów z życia wziętych może być następujący kod:

Przykład 3JavaScript
1
2
3
4
5
6
7
8
var element = $('.element');
$('.element').hasClass('focus') && (function () {
  element.sibling().removeClass('active');
  $('#activity').text('Element ma klasę .focus');
  setTimeout(function () {
    wykonajAnimacje(element);
  }, 1000);
});

Jeśli element ma klasę focus, to wykonaj zawartość anonimowej funkcji. Jest to proste i efektywne rozwiązanie.

Sekcja 5Funkcje z parametrami o wartościach domyślnych

W języku JavaScript w definicji funkcji nie możemy definiować wartości domyślnych parametrów, tak jak to ma miejsce chociażby w języku PHP. Na szczęście, istnieje inne wyjście - przypisania warunkowe.

Przykład 4JavaScript
1
2
3
4
function (active) {
  var isActive = active || false;
  ...
}

Wyżej wymieniona funkcja przyjmuje jeden parametr: active, jeśli jej wartość jest zdefiniowana, to zmienna isActive przyjmie wartość true, a jeśli nie jest zdefiniowana to zmienna przyjmie wartość domyślną (zdefiniowaną przez programistę).

Sekcja 6Podsumowanie

Wyżej wymienione przykłady to tylko część możliwości jakie daje nam operowanie na wartościach zmiennych za pomocą operatorów bitowych i logicznych. W części przypadków znacząco to przyspiesza działanie aplikacji, a w części przypadków pozwala na redukcję wagi pliku skryptu.
Takie rozwiązania są bardzo użyteczne, ale bardzo często jest to osiągane zmniejszeniem czytelności kodu.
W większości przypadków, czytelność kodu w wersji rozwojowej jest więcej warta niż mikro optymalizacje. Dzięki czytelności kodu możemy zaoszczędzić czas poświęcony na rozwiązywanie problemów z kodem lub poświęcony na wprowadzanie nowych funkcjonalności. Warto jednak mieć na uwadze sposoby na optymalizację kodu wymienione wyżej, ponieważ mogą się przydać w krytycznych sytuacjach.

Udostępnij
Uwagi

O autorze

Staff Software Engineer

Piszę na tym blogu od 2009 roku, a strony i aplikacje webowe tworzę zawodowo od 14 lat. Obecnie w Bishop Fox prowadzę frontend platformy Cosmos, od samego początku projektu. Wcześniej pracowałem m.in. w OLX, KUDO, Auto1 i eZ Systems. Piszę tu o tym, czego nauczyłem się w praktyce: o JavaScripcie, TypeScripcie, Reakcie, CSS-ie i architekturze frontendu. Występowałem też jako prelegent na konferencjach w Polsce i Europie. Masz pytanie albo pomysł na wpis? Daj znać!