Kurs JavaScript i TypeScript · Moduł 1: Podstawy JavaScript
Operatory arytmetyczne i przypisania
W tej lekcji9
Poranna odprawa w centrum kontroli Parku Jurajskiego zaczyna się od liczb. Ile mięsa wydać raptorom? Ile jaj nie zmieści się w inkubatorach? Ilu zwiedzających przeszło przez bramę? Dr. Rex zleca te obliczenia systemom parku, a JavaScript daje im dwie rodziny narzędzi: operatory arytmetyczne, które liczą, oraz operatory przypisania, które zapisują wynik w zmiennej.
Cztery podstawowe działania
Dodawanie, odejmowanie, mnożenie i dzielenie zapisujesz znakami +, -, * oraz /, a JavaScript liczy jak kalkulator w laboratorium:
1// Dodawanie (+)
2let iloscRaptorów = 5;
3let noweWyklute = 3;
4let całkowitaIloscRaptorów = iloscRaptorów + noweWyklute; // 8
5
6// Odejmowanie (-)
7let dinozauryOgółem = 57;
8let przeniesioneDinozaury = 12;
9let pozostałeDinozaury = dinozauryOgółem - przeniesioneDinozaury; // 45
10
11// Mnożenie (*)
12let dzienneZapotrzebowanieNaPokarm = 20; // kg na dinozaura
13let iloscTroodontów = 7;
14let całkowiteZapotrzebowanie = dzienneZapotrzebowanieNaPokarm * iloscTroodontów; // 140 kg
15
16// Dzielenie (/)
17let zapasyMięsa = 1500; // kg
18let dzienneZużycie = 300; // kg
19let wystarczyNaDni = zapasyMięsa / dzienneZużycie; // 5 dniZwróć uwagę, czego te działania nie robią: iloscRaptorów i dinozauryOgółem zachowują swoje wartości, a wynik trafia do nowej zmiennej. Dzielenie nie obcina też ułamków: 7 / 2 daje 3.5, bo liczby całkowite i ułamkowe to w JavaScript jeden typ number.
Reszta z dzielenia i potęgowanie
Operator % zwraca resztę z dzielenia: 17 jaj po 4 na inkubator to cztery pełne inkubatory i jedno jajo w kolejce. Operator ** podnosi liczbę do potęgi:
1// Reszta z dzielenia (%)
2let liczbaJaj = 17;
3let pojemnośćInkubatora = 4;
4let jajaPozostałePoZapełnieniuInkubatorów = liczbaJaj % pojemnośćInkubatora; // 1
5
6// Potęgowanie (**)
7let początkowaPopulacja = 2;
8let lataRozrodu = 3;
9let szacowanaPopulacja = początkowaPopulacja ** lataRozrodu; // 2^3 = 8Mimo znaku % ten operator nie ma nic wspólnego z procentami: 10 % 3 to 1, bo 10 = 3 · 3 + 1. Z kolei 2 ** 3 oznacza 2 · 2 · 2, czyli 8, a nie 6 ani 9.
Inkrementacja i dekrementacja
Liczniki często zmieniają się o jeden: wchodzi zwiedzający, alarm spada o poziom. Na taką okazję JavaScript ma skróty ++ i --:
1// Inkrementacja (++) - zwiększenie o 1
2let odwiedzającyPark = 120;
3odwiedzającyPark++; // teraz odwiedzającyPark = 121
4
5// Dekrementacja (--) - zmniejszenie o 1
6let poziomZagrożenia = 5;
7poziomZagrożenia--; // teraz poziomZagrożenia = 4W przeciwieństwie do + i - te operatory zmieniają samą zmienną, więc na stałej const kończą się błędem TypeError. Mają też dwie formy, które różnią się wartością zwracaną w chwili użycia:
1let a = 5;
2console.log(++a); // 6 - najpierw zwiększa, potem zwraca
3let b = 5;
4console.log(b++); // 5 - najpierw zwraca starą wartość, potem zwiększa
5console.log(b); // 6Obie zmienne kończą z wartością 6, różni się tylko to, co trafia do console.log w tej samej linii. Moja rada: pisz ++ w osobnej linii, a nie w środku większego wyrażenia.
Kolejność działań
Dr. Rex liczy dzienne zapotrzebowanie mięsożerców: pięć małych drapieżników zjada po 50 kg, trzy duże po 300 kg. Oto próba stażysty i poprawka:
1let małeMięsożerne = 5;
2let dużeMięsożerne = 3;
3let dzienneSpożycieMałych = 50; // kg
4let dzienneSpożycieDużych = 300; // kg
5
6// Nieprawidłowe obliczenie - zapomniany składnik
7let nieprawidłoweZużycie = małeMięsożerne + dużeMięsożerne * dzienneSpożycieDużych;
8console.log(nieprawidłoweZużycie); // 905 (nieprawidłowy wynik!)
9
10// Prawidłowe obliczenie (z nawiasami)
11let prawidłoweZużycie = (małeMięsożerne * dzienneSpożycieMałych) + (dużeMięsożerne * dzienneSpożycieDużych);
12console.log(prawidłoweZużycie); // 1150 kg (prawidłowy wynik)
13
14// Tu nawiasy naprawdę zmieniają wynik
15console.log((małeMięsożerne + dużeMięsożerne) * dzienneSpożycieDużych); // 2400Skąd 905? Mnożenie ma pierwszeństwo, więc JavaScript liczy 3 * 300 i dodaje 5, czyli samą liczbę zwierząt. Błąd tkwi we wzorze, a nie w kolejności. W poprawnej wersji nawiasy służą czytelności, bo bez nich wynik też wyniósłby 1150. Wynik zmieniają dopiero w ostatniej linii, gdzie każą najpierw dodać osobniki.
Standardowa kolejność działań (PEMDAS):
- Nawiasy -
( ) - Potęgi -
** - Mnożenie i dzielenie -
*/ - Dodawanie i odejmowanie -
+-
Skrót pochodzi od angielskich nazw poziomów: Parentheses, Exponents, Multiplication/Division, Addition/Subtraction. Operator % stoi na poziomie * i /, a działania z jednego poziomu idą od lewej do prawej. Wyjątkiem jest potęgowanie, liczone od prawej: 2 ** 3 ** 2 to 512. Pełną tabelę poznasz w lekcji o priorytecie operatorów.
Operatory przypisania
Liczników zwykle nie ustawia się od nowa, tylko aktualizuje. Zamiast pisać zwiedzający = zwiedzający + 50, możesz połączyć działanie z przypisaniem w jednym operatorze:
1// Podstawowe przypisanie (=)
2let liczbaTRexów = 2;
3
4// Przypisanie z dodawaniem (+=)
5let zwiedzający = 100;
6zwiedzający += 50; // równoważne zwiedzający = zwiedzający + 50; (teraz 150)
7
8// Przypisanie z odejmowaniem (-=)
9let zasobyPaliwa = 1000;
10zasobyPaliwa -= 250; // równoważne zasobyPaliwa = zasobyPaliwa - 250; (teraz 750)Zapis count += 5 znaczy dokładnie to samo co count = count + 5: odczytaj wartość, dodaj 5 i zapisz wynik w tej samej zmiennej. Tak samo działają pozostałe operatory:
1// Przypisanie z mnożeniem (*=)
2let populacjaDilofozaurów = 4;
3populacjaDilofozaurów *= 2; // równoważne populacjaDilofozaurów = populacjaDilofozaurów * 2; (teraz 8)
4
5// Przypisanie z dzieleniem (/=)
6let racjaPokarmowa = 1200;
7racjaPokarmowa /= 4; // równoważne racjaPokarmowa = racjaPokarmowa / 4; (teraz 300)
8
9// Przypisanie z resztą z dzielenia (%=)
10let miejscaWJeepach = 20;
11miejscaWJeepach %= 6; // równoważne miejscaWJeepach = miejscaWJeepach % 6; (teraz 2)
12
13// Przypisanie z potęgowaniem (**=)
14let wzrostPopulacji = 2;
15wzrostPopulacji **= 3; // równoważne wzrostPopulacji = wzrostPopulacji ** 3; (teraz 8)Operator złożony nadpisuje zmienną, więc tak jak ++ nie zadziała na stałej const. Polecam go zamiast pełnego zapisu: nazwa zmiennej pojawia się raz, więc nie zrobisz literówki, przepisując ją drugi raz.
Łączenie operatorów w praktyce
Prawdziwe zadania łączą kilka operatorów. Po wykluciu się pięciu młodych trzeba zaktualizować pokoje w wylęgarni, policzyć zapełnienie i sprawdzić, czy wystarczy opiekunów (jeden na trzy dinozaury):
1// Scenariusz: Aktualizacja zasobów parku po wykluciu się nowych dinozaurów
2
3let dostępnePokoje = 50;
4let zajętePokoje = 30;
5let noweDinozaury = 5;
6let personelOpiekuńczy = 15;
7
8// Aktualizacja pokoi: nowe dinozaury zajmują wolne miejsca
9dostępnePokoje -= noweDinozaury; // 45
10zajętePokoje += noweDinozaury; // 35
11
12// Obliczenie nowego poziomu zapełnienia (w procentach)
13let poziomZapełnienia = zajętePokoje / (zajętePokoje + dostępnePokoje) * 100;
14console.log(`Poziom zapełnienia parku: ${poziomZapełnienia}%`); // 43.75%
15
16// Obliczenie potrzebnego personelu (1 opiekun na 3 dinozaury)
17let wymaganyPersonel = Math.ceil(zajętePokoje / 3); // 12
18let dodatkowyPersonel = wymaganyPersonel - personelOpiekuńczy;
19
20if (dodatkowyPersonel > 0) {
21 console.log(`Potrzebujemy zatrudnić ${dodatkowyPersonel} dodatkowych opiekunów.`);
22} else {
23 console.log("Mamy wystarczającą liczbę personelu.");
24}Aktualizujemy obie zmienne, bo młode zajmują wolne pokoje, a ich suma zostaje bez zmian: 80. Math.ceil zaokrągla w górę, bo nie da się zatrudnić dwóch trzecich opiekuna: 35 / 3 daje 12 osób. Mamy 15, więc program wypisze drugi komunikat. Napis w grawisach z ${...} to template literal, a if wybiera jedną z dwóch ścieżek. Oba narzędzia omówimy w kolejnych lekcjach.
Uwaga na tekst
Operator + ma podwójną naturę: gdy choć jedna strona jest tekstem, skleja napisy zamiast dodawać. To konkatenacja z lekcji o konwersji typów:
1// Uwaga na operacje na stringach!
2let raport = "Raport #";
3let numerRaportu = 42;
4let pełnyRaport = raport + numerRaportu; // "Raport #42" (konkatenacja stringów)
5
6// Różnica między numerycznymi operacjami a konkatenacją stringów
7let wynik1 = 5 + 10; // 15 (liczba)
8let wynik2 = "5" + "10"; // "510" (string)
9let wynik3 = "5" + 10; // "510" (string, 10 zostało skonwertowane na string)
10let wynik4 = 5 + "10"; // "510" (string, 5 zostało skonwertowane na string)Pozostałe operatory arytmetyczne zamieniają tekst na liczbę, więc "5" - 2 daje 3. Dlatego dane z formularza zamieniaj przez Number(), zanim dodasz je do licznika.
Podsumowanie
Operatory arytmetyczne i przypisania są fundamentem bardziej złożonych operacji. Pozwalają na:
- wykonywanie działań matematycznych (
+,-,*,/,%,**), - inkrementację i dekrementację wartości (
++,--), - zwięzłe aktualizowanie zmiennych (
+=,-=,*=,/=,%=,**=).
Pilnuj kolejności działań i typów danych: pomyłka w obliczeniach bywa groźna w parku pełnym drapieżników. W następnej lekcji poznasz operatory porównania i logiczne, dzięki którym systemy parku podejmują decyzje.
Praktyka
W piaskownicy czeka konsola centrum kontroli: sumy populacji, 10 % 3, 2 ** 10, porównanie ++a z b++ i aktualizacje zapasów. Zmieniaj liczby i przewiduj każdy wynik, zanim pojawi się w konsoli. Na końcu czekają dwa zadania do samodzielnego rozwiązania.
Kod do tej lekcji: index.js
1// Operatory arytmetyczne i przypisania
2// Obliczenia w systemie zarządzania Parkiem Jurajskim
3
4// === Operatory arytmetyczne ===
5console.log("=== Operatory arytmetyczne ===");
6
7let raptory = 8;
8let triceratopsy = 12;
9
10// Dodawanie, odejmowanie, mnożenie, dzielenie
11console.log("Suma:", raptory + triceratopsy); // 20
12console.log("Różnica:", triceratopsy - raptory); // 4
13console.log("Iloczyn:", raptory * 3); // 24
14console.log("Iloraz:", triceratopsy / 4); // 3
15
16// Reszta z dzielenia (modulo)
17console.log("Reszta 10 % 3:", 10 % 3); // 1
18
19// Potęgowanie
20console.log("2 ** 10:", 2 ** 10); // 1024
21
22// === Inkrementacja i dekrementacja ===
23console.log("\n=== Inkrementacja / Dekrementacja ===");
24
25let populacja = 50;
26populacja++; // 51
27console.log("Po ++:", populacja);
28populacja--; // 50
29console.log("Po --:", populacja);
30
31// Różnica pre vs post
32let a = 5;
33console.log("++a:", ++a); // 6 (najpierw zwiększa, potem zwraca)
34let b = 5;
35console.log("b++:", b++); // 5 (najpierw zwraca, potem zwiększa)
36console.log("b po b++:", b); // 6
37
38// === Operatory przypisania ===
39console.log("\n=== Operatory przypisania ===");
40
41let zapasy = 1000;
42zapasy += 200; // zapasy = zapasy + 200
43console.log("Po += 200:", zapasy);
44
45zapasy -= 150; // zapasy = zapasy - 150
46console.log("Po -= 150:", zapasy);
47
48zapasy *= 2; // zapasy = zapasy * 2
49console.log("Po *= 2:", zapasy);
50
51zapasy /= 4; // zapasy = zapasy / 4
52console.log("Po /= 4:", zapasy);
53
54// Twoje zadanie:
55// 1. Oblicz całkowite zapotrzebowanie na pokarm (dinozaury * kg/dzień)
56// 2. Użyj operatorów przypisania do aktualizacji stanu zasobów
57Zapamiętaj: operator arytmetyczny tylko liczy, a operator przypisania zapisuje wynik, jak laborant, który najpierw waży porcję, a potem wpisuje ją do dziennika karmień.
Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Jaki jest wynik wyrażenia 10 % 3 w JavaScript?
2. Co zwróci wyrażenie 2 ** 3 w JavaScript?
3. Co jest równoważne zapisowi: count += 5?
Zadania praktyczne w grze
- Układanie w pionie
Uporządkuj operatory arytmetyczne od najwyższego priorytetu do najniższego: