Kurs JavaScript i TypeScript · Moduł 1: Podstawy JavaScript
Priorytet operatorów
W tej lekcji7
W Parku Jurajskim, protokoły bezpieczeństwa muszą być ściśle przestrzegane i wykonywane w odpowiedniej kolejności. Na przykład, zanim otworzy się bramę do wybiegu z Tyranozaurem, należy upewnić się, że wszystkie inne drzwi są zamknięte i że pracownicy są w bezpiecznych strefach. Kolejność tych działań ma kluczowe znaczenie.
Podobnie w JavaScript, operatory mają swój priorytet (precedence), który określa kolejność ich wykonania w wyrażeniach. Zrozumienie tej hierarchii jest niezbędne do tworzenia poprawnych i przewidywalnych wyrażeń.
Czym jest priorytet operatorów?
Priorytet operatorów to reguła, która określa kolejność, w jakiej operatory są wykonywane w złożonych wyrażeniach. Operatory o wyższym priorytecie są wykonywane przed operatorami o niższym priorytecie.
Wyobraźmy sobie, że w Parku Jurajskim mamy listę zadań do wykonania z różnym priorytetem:
- Najwyższy priorytet: Sprawdzenie zasilania w ogrodzeniach elektrycznych
- Średni priorytet: Sprawdzenie ilości pożywienia dla dinozaurów
- Niski priorytet: Aktualizacja informacji dla odwiedzających
Podobnie, JavaScript ma swoją hierarchię priorytetów dla operatorów.
Tabela priorytetów operatorów
Poniżej przedstawiono uproszczoną tabelę priorytetów operatorów w JavaScript, od najwyższego do najniższego:
| Priorytet | Kategoria | Operatory |
|---|---|---|
| 19 | Grupowanie | ( ... ) |
| 18 | Dostęp do właściwości i elementy tablicy | . [] ?. |
| 17 | Wywołanie funkcji | ... ( ... ) |
| 16 | Operatory postfiksowe | ++ -- |
| 15 | Operatory prefiksowe | ! ~ + - ++ -- typeof void delete |
| 14 | Potęgowanie | ** |
| 13 | Mnożenie, dzielenie, modulo | * / % |
| 12 | Dodawanie, odejmowanie | + - |
| 11 | Przesunięcie bitowe | << >> >>> |
| 10 | Porównania (nierówności) | < > <= >= instanceof in |
| 9 | Równość | == != === !== |
| 8 | Bitowe AND | & |
| 7 | Bitowe XOR | ^ |
| 6 | Bitowe OR | | |
| 5 | Logiczne AND | && |
| 4 | Logiczne OR | || |
| 3 | Nullish coalescing | ?? |
| 2 | Operator warunkowy | ? : |
| 1 | Przypisanie | = += -= *= /= %= <<= >>= >>>= &= ^= |= **= |
| 0 | Operator przecinka | , |
Przykłady z Parku Jurajskiego
Przyjrzyjmy się, jak priorytet operatorów działa w praktyce, wykorzystując przykłady z codziennej pracy w Parku Jurajskim:
Przykład 1: Operacje arytmetyczne
1// Obliczenie ilości pożywienia potrzebnego dla dinozaurów
2
3let małeMięsożerne = 5;
4let średnieMięsożerne = 3;
5let dużeMięsożerne = 2;
6
7let dzienneZużycieMałych = 50; // kg
8let dzienneZużycieŚrednich = 150; // kg
9let dzienneZużycieDużych = 300; // kg
10
11// Bez nawiasów - priorytet operatorów decyduje o kolejności
12let całkowitePożywienie = małeMięsożerne * dzienneZużycieMałych + średnieMięsożerne * dzienneZużycieŚrednich + dużeMięsożerne * dzienneZużycieDużych;
13
14console.log(całkowitePożywienie); // 1300 kg
15
16// Mnożenie (*) ma wyższy priorytet niż dodawanie (+), więc powyższe wyrażenie jest równoważne:
17let całkowitePożywienie2 = (małeMięsożerne * dzienneZużycieMałych) + (średnieMięsożerne * dzienneZużycieŚrednich) + (dużeMięsożerne * dzienneZużycieDużych);
18
19console.log(całkowitePożywienie2); // 1300 kg (ten sam wynik)Przykład 2: Operatory logiczne i porównania
1// Sprawdzenie warunków otwarcia wybiegu dla zwiedzających
2
3let temperaturaPowietrza = 28; // stopnie Celsjusza
4let wilgotność = 60; // procent
5let prędkośćWiatru = 15; // km/h
6let poziomZagrożenia = 2; // skala 1-5
7let dostępnyPersonel = 5; // liczba pracowników
8let wymaganyPersonel = 3; // minimalna liczba
9
10// Złożony warunek bez nawiasów
11let otwartyWybieg = temperaturaPowietrza > 20 && wilgotność < 80 && prędkośćWiatru < 20 || poziomZagrożenia <= 2 && dostępnyPersonel >= wymaganyPersonel;
12
13// Jak JavaScript to interpretuje? Operator && ma wyższy priorytet niż ||
14// Powyższe wyrażenie jest równoważne:
15let otwartyWybieg2 = ((temperaturaPowietrza > 20 && wilgotność < 80 && prędkośćWiatru < 20) || (poziomZagrożenia <= 2 && dostępnyPersonel >= wymaganyPersonel));
16
17console.log(otwartyWybieg); // true
18console.log(otwartyWybieg2); // true (ten sam wynik)Przykład 3: Operator warunkowy i przypisanie
1// Określenie statusu bezpieczeństwa dla różnych gatunków dinozaurów
2
3let gatunek = "Velociraptor";
4let agresywność = 4; // skala 1-5
5let wysokośćOgrodzenia = 5; // metry
6
7// Złożone wyrażenie z operatorem warunkowym i przypisaniem
8let statusBezpieczeństwa = gatunek === "Tyranozaur" || gatunek === "Spinozaur" || agresywność >= 4 ? "Wysoki" : agresywność >= 3 ? "Średni" : "Niski";
9
10console.log(statusBezpieczeństwa); // "Wysoki" (dla Velociraptora z agresywnością 4)
11
12// Bardziej czytelna wersja z nawiasami pokazująca faktyczną kolejność ewaluacji:
13let statusBezpieczeństwa2 = (gatunek === "Tyranozaur" || gatunek === "Spinozaur" || agresywność >= 4) ? "Wysoki" : (agresywność >= 3 ? "Średni" : "Niski");
14
15console.log(statusBezpieczeństwa2); // "Wysoki" (ten sam wynik)Przykład 4: Grupowanie (najwyższy priorytet)
1// Obliczanie szacowanej populacji dinozaurów po kilku pokoleniach
2
3let początkowa_populacja = 2;
4let wskaźnik_rozrodczości = 3; // średnia liczba potomstwa
5let pokolenia = 2;
6
7// Obliczenie bez nawiasów
8let szacowana_populacja1 = początkowa_populacja * wskaźnik_rozrodczości ** pokolenia;
9console.log(szacowana_populacja1); // 18 (2 * 3² = 2 * 9 = 18)
10
11// Zmiana kolejności za pomocą nawiasów (grupowanie)
12let szacowana_populacja2 = (początkowa_populacja * wskaźnik_rozrodczości) ** pokolenia;
13console.log(szacowana_populacja2); // 36 ((2 * 3)² = 6² = 36)Przykład 5: Łączenie różnych operatorów
1// Kalkulator stanu zapasów po dostawie
2
3let obecneZasoby = 500; // kg
4let dostawaTygodniowa = 200; // kg
5let średnieZużycieDzienne = 50; // kg
6let dniTygodnia = 7;
7let czyDziałająLodówki = true;
8let maksymalnaZdolnośćMagazynowa = 1000; // kg
9
10// Złożony kalkulator bez wyraźnego grupowania
11let nowyStan = obecneZasoby + dostawaTygodniowa - średnieZużycieDzienne * dniTygodnia * (czyDziałająLodówki ? 1 : 1.5);
12
13console.log(nowyStan); // 350 kg (500 + 200 - 50 * 7 * 1)
14
15// Bardziej czytelna wersja z nawiasami pokazująca faktyczną kolejność ewaluacji:
16let nowyStan2 = obecneZasoby + dostawaTygodniowa - (średnieZużycieDzienne * dniTygodnia * (czyDziałająLodówki ? 1 : 1.5));
17
18console.log(nowyStan2); // 350 kg (ten sam wynik)
19
20// Sprawdzenie, czy nowy stan nie przekracza pojemności magazynu
21let stanProcentowy = nowyStan / maksymalnaZdolnośćMagazynowa * 100;
22console.log(stanProcentowy + "%"); // 35%Rekomendacje dotyczące używania nawiasów
Mimo że JavaScript ma ściśle określony priorytet operatorów, używanie nawiasów do jawnego określania kolejności wykonywania operacji ma kilka zalet:
Zwiększa czytelność kodu - nawet jeśli znasz priorytet operatorów, jawne nawiasy czynią kod bardziej czytelnym dla ciebie i innych.
Zapobiega błędom - w złożonych wyrażeniach łatwo popełnić błąd związany z kolejnością wykonywania operacji.
Ułatwia modyfikację - jeśli później zmienisz wyrażenie, nawiasy mogą zapobiec nieoczekiwanym zmianom w logice.
1// Przykład używania nawiasów dla zwiększenia czytelności
2
3// Mniej czytelne:
4let czyBezpieczny = !ogrodzeniePrzerwane && zasilanieAktywne || trybAwaryjny && ewakuacjaZakończona;
5
6// Bardziej czytelne z nawiasami:
7let czyBezpieczny2 = (!ogrodzeniePrzerwane && zasilanieAktywne) || (trybAwaryjny && ewakuacjaZakończona);Łączność (associativity) operatorów
Oprócz priorytetu, ważną cechą operatorów jest ich łączność, która określa kolejność wykonywania operatorów o tym samym priorytecie:
- Łączność od lewej do prawej (left-to-right): większość operatorów, np.
+,-,*,/ - Łączność od prawej do lewej (right-to-left): niektóre operatory, np.
=,**,+=, operatory jednoargumentowe (!,++,--)
1// Przykład łączności od lewej do prawej
2let a = 5 - 3 - 2; // (5 - 3) - 2 = 0
3
4// Przykład łączności od prawej do lewej
5let b = 2;
6let c = 3;
7let d = 4;
8let e = b = c = d; // b = (c = (d)) = 4
9console.log(b, c, d, e); // 4, 4, 4, 4
10
11// Potęgowanie jest również łączone od prawej do lewej
12let f = 2 ** 3 ** 2; // 2 ** (3 ** 2) = 2 ** 9 = 512
13let g = (2 ** 3) ** 2; // 8 ** 2 = 64
14console.log(f, g); // 512, 64Praktyczne wskazówki z Parku Jurajskiego
W Parku Jurajskim, niejednoznaczność w protokołach bezpieczeństwa może prowadzić do katastrofalnych skutków. Podobnie, niejednoznaczne wyrażenia w kodzie mogą prowadzić do nieoczekiwanych wyników. Oto kilka wskazówek:
Używaj nawiasów, gdy łączysz różne typy operatorów - szczególnie gdy mieszasz operatory arytmetyczne, logiczne i warunkowe.
Rozbijaj złożone wyrażenia na prostsze - dla większej czytelności i łatwiejszego debugowania, możesz przypisać pośrednie wyniki do zmiennych.
1// Zamiast:
2let rezultat = a * b + c * d && e > f || g <= h;
3
4// Lepiej:
5let część1 = a * b + c * d;
6let część2 = e > f;
7let część3 = g <= h;
8let rezultat = część1 && część2 || część3;- Bądź ostrożny z operatorami postfix i prefix - operatory
++i--mogą prowadzić do nieoczekiwanych wyników, gdy są używane w złożonych wyrażeniach.
1let ilośćDinozaurów = 5;
2let nowaIlość = ilośćDinozaurów++ * 2; // najpierw użyje wartości 5, potem zwiększy ilośćDinozaurów do 6
3console.log(nowaIlość, ilośćDinozaurów); // 10, 6
4
5let ilośćKlatek = 5;
6let nowaIlośćKlatek = ++ilośćKlatek * 2; // najpierw zwiększy ilośćKlatek do 6, potem użyje tej wartości
7console.log(nowaIlośćKlatek, ilośćKlatek); // 12, 6Podsumowanie
Priorytet operatorów w JavaScript, podobnie jak hierarchia zadań w Parku Jurajskim, określa kolejność wykonywania operacji. Znajomość tej hierarchii jest kluczowa dla pisania poprawnego i przewidywalnego kodu.
Najważniejsze rzeczy do zapamiętania:
- Grupowanie za pomocą nawiasów ma najwyższy priorytet i pozwala kontrolować kolejność wykonywania operacji.
- Operatory arytmetyczne (
*,/) mają wyższy priorytet niż (+,-). - Operatory porównania (
>,<,>=,<=) mają wyższy priorytet niż operatory równości (==,===,!=,!==). - Operator logiczny AND (
&&) ma wyższy priorytet niż OR (||). - Operatory przypisania (
=,+=,-=, itd.) mają jeden z najniższych priorytetów.
Pamiętaj, że w przypadku wątpliwości, zawsze lepiej użyć nawiasów dla jednoznaczności - podobnie jak w Parku Jurajskim, gdzie lepiej jest nadmiarowo zabezpieczyć się przed niespodziewanymi sytuacjami, niż ryzykować nieprzewidziane konsekwencje.
W następnej lekcji przyjrzymy się strukturom kontrolnym - instrukcjom warunkowym, które pozwalają na podejmowanie decyzji w zależności od określonych warunków - niezbędnym do zarządzania tak złożonym przedsięwzięciem jak Park Jurajski.
Kod do tej lekcji: index.js
1// Priorytet operatorów w JavaScript
2// Kolejność wykonywania operacji
3
4// === Priorytet arytmetyczny ===
5console.log("=== Priorytet arytmetyczny ===");
6
7// Mnożenie przed dodawaniem
8console.log("2 + 3 * 4 =", 2 + 3 * 4); // 14 (nie 20!)
9console.log("(2 + 3) * 4 =", (2 + 3) * 4); // 20 (nawiasy zmieniają kolejność)
10
11// Potęgowanie ma wyższy priorytet niż mnożenie
12console.log("2 * 3 ** 2 =", 2 * 3 ** 2); // 18 (nie 36!)
13console.log("(2 * 3) ** 2 =", (2 * 3) ** 2); // 36
14
15// === Priorytet logiczny ===
16console.log("\n=== Priorytet logiczny ===");
17
18// AND (&&) ma wyższy priorytet niż OR (||)
19let a = true, b = false, c = true;
20console.log("true || false && false:", true || false && false); // true
21// Równoważnie: true || (false && false) -> true || false -> true
22
23console.log("(true || false) && false:", (true || false) && false); // false
24
25// === Porównanie i logika ===
26console.log("\n=== Łączenie porównania i logiki ===");
27
28let wiek = 25;
29let waga = 7000;
30let dieta = "mięsożerca";
31
32// Bez nawiasów - może być mylące
33let niebezpieczny = dieta === "mięsożerca" && waga > 5000 || wiek > 30;
34console.log("Bez nawiasów:", niebezpieczny);
35
36// Z nawiasami - jasne i czytelne
37let niebezpiecznyJasny = (dieta === "mięsożerca" && waga > 5000) || wiek > 30;
38console.log("Z nawiasami:", niebezpiecznyJasny);
39
40// === Operator warunkowy (ternary) ===
41console.log("\n=== Operator warunkowy ===");
42let status = waga > 5000 ? "Duży dinozaur" : "Mały dinozaur";
43console.log("Status:", status);
44
45// Twoje zadanie:
46// 1. Oblicz wyrażenie z różnymi priorytetami
47// 2. Użyj nawiasów aby zmienić kolejność operacji
48// 3. Użyj operatora warunkowego (ternary)
49Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Który operator logiczny ma wyższy priorytet w JavaScript?
2. Jak wymusić inną kolejność wykonywania operacji niż domyślna w JavaScript?
Zadania praktyczne w grze
- Układanie w pionie
Uporządkuj kategorie operatorów od najwyższego priorytetu do najniższego: