Kurs JavaScript i TypeScript · Moduł 1: Podstawy JavaScript
Operatory porównania i logiczne
W tej lekcji6
W Parku Jurajskim system zabezpieczeń nieustannie podejmuje decyzje: czy ogrodzenie elektryczne ma wystarczająco dużo energii? Czy poziom bezpieczeństwa jest odpowiedni dla tego gatunku dinozaura? Czy warunki pogodowe pozwalają na otwarcie atrakcji?
JavaScript, podobnie jak system zabezpieczeń w parku, korzysta z operatorów porównania i logicznych do podejmowania decyzji w kodzie.
Operatory porównania
Operatory porównania pozwalają na porównywanie wartości i zwracają wartość logiczną (true lub false). Pracując w Parku Jurajskim, system kontroli musi nieustannie wykonywać podobne porównania:
1// Operator równości (==)
2let poziomZagrożenia = 3;
3let maksymalnyBezpiecznyPoziom = 3;
4console.log(poziomZagrożenia == maksymalnyBezpiecznyPoziom); // true - poziomy są równe
5
6// Operator ścisłej równości (===)
7let ilośćDinozaurów = "5";
8let oczekiwanaIlość = 5;
9console.log(ilośćDinozaurów == oczekiwanaIlość); // true - wartości są równe, ale typy różne
10console.log(ilośćDinozaurów === oczekiwanaIlość); // false - różne typy (string vs number)
11
12// Operator nierówności (!=)
13let dostępneZasoby = 500;
14let wymaganeZasoby = 600;
15console.log(dostępneZasoby != wymaganeZasoby); // true - wartości są różne
16
17// Operator ścisłej nierówności (!==)
18let statusOgrodzenia = "aktywne";
19let wymaganyStatus = "aktywne";
20console.log(statusOgrodzenia !== wymaganyStatus); // false - są identyczne (te same stringi)
21
22// Operator większości (>)
23let temperaturaTropisferowa = 38; // w stopniach Celsjusza
24let bezpiecznaTemperatura = 35;
25console.log(temperaturaTropisferowa > bezpiecznaTemperatura); // true - temperatura jest wyższa
26
27// Operator mniejszości (<)
28let poziomWody = 80; // procent pojemności
29let krytycznyPoziom = 20;
30console.log(poziomWody < krytycznyPoziom); // false - poziom wody nie jest niższy od krytycznego
31
32// Operator większy lub równy (>=)
33let liczbaPracowników = 45;
34let minimalnaObsada = 45;
35console.log(liczbaPracowników >= minimalnaObsada); // true - dokładnie minimalna wymagana liczba
36
37// Operator mniejszy lub równy (<=)
38let obciążenieSystemu = 75; // procent
39let maksymalneObciążenie = 80;
40console.log(obciążenieSystemu <= maksymalneObciążenie); // true - obciążenie jest poniżej maksimumRóżnica między == i ===
W Parku Jurajskim, precyzja jest kluczowa. Podobnie w JavaScript, istnieje ważna różnica między operatorami równości:
==(równość) - porównuje tylko wartości, wykonując konwersję typów jeśli to konieczne===(ścisła równość) - porównuje wartości i typy danych
1// Przykłady z Parku Jurajskiego:
2
3// Scenariusz 1: Konwersja z bazy danych (string) do wartości liczbowej
4let raportowanaIlośćRaptorów = "6"; // dane z systemu jako string
5let rzeczywistaIlośćRaptorów = 6; // wartość liczbowa
6
7// Porównanie z konwersją typów
8if (raportowanaIlośćRaptorów == rzeczywistaIlośćRaptorów) {
9 console.log("Liczby raptorów się zgadzają"); // to się wykona
10}
11
12// Porównanie bez konwersji typów
13if (raportowanaIlośćRaptorów === rzeczywistaIlośćRaptorów) {
14 console.log("Ten komunikat się nie wyświetli");
15} else {
16 console.log("Wykryto rozbieżność w typach danych!"); // to się wykona
17}
18
19// Scenariusz 2: Porównanie wartości nieznanych (null i undefined)
20let nieznanyStatus = null;
21let nieokreślonyStatus; // automatycznie będzie undefined
22
23console.log(nieznanyStatus == nieokreślonyStatus); // true (== traktuje null i undefined jako równe)
24console.log(nieznanyStatus === nieokreślonyStatus); // false (=== rozróżnia null od undefined)Porównywanie obiektów
Podobnie jak dwa Velociraptory mogą wyglądać podobnie, ale być różnymi osobnikami, obiekty w JavaScript są porównywane przez referencję, a nie wartość:
1// Dwa dinozaury o tych samych cechach, ale to różne osobniki
2let raptor1 = { gatunek: "Velociraptor", wiek: 3, agresywność: "wysoka" };
3let raptor2 = { gatunek: "Velociraptor", wiek: 3, agresywność: "wysoka" };
4
5console.log(raptor1 == raptor2); // false - różne obiekty w pamięci
6console.log(raptor1 === raptor2); // false - różne obiekty w pamięci
7
8// Przypisanie tej samej referencji
9let referencjaNaRaptora = raptor1;
10console.log(raptor1 === referencjaNaRaptora); // true - ta sama referencja w pamięciOperatory logiczne
W Parku Jurajskim decyzje rzadko są proste. Czy otworzyć atrakcję? To zależy od pogody, dostępności personelu, statusu bezpieczeństwa i innych czynników. Operatory logiczne pozwalają na łączenie warunków:
1// Operator AND (&&) - zwraca true tylko gdy oba warunki są true
2let ogrodzenieDziała = true;
3let systemŚledzeniaDinozaurów = true;
4let bezpieczeństwoZapewnione = ogrodzenieDziała && systemŚledzeniaDinozaurów;
5console.log(bezpieczeństwoZapewnione); // true - oba systemy działają
6
7// Operator OR (||) - zwraca true gdy przynajmniej jeden warunek jest true
8let zasilanieGłówne = false;
9let zasilanieZapasowe = true;
10let parkMaZasilanie = zasilanieGłówne || zasilanieZapasowe;
11console.log(parkMaZasilanie); // true - przynajmniej jedno źródło zasilania działa
12
13// Operator NOT (!) - odwraca wartość logiczną
14let parkZamknięty = false;
15let parkOtwarty = !parkZamknięty;
16console.log(parkOtwarty); // true - przeciwieństwo zamknięcia to otwarcieZłożone warunki logiczne
W rzeczywistości, systemy Parku Jurajskiego muszą rozważać wiele czynników jednocześnie:
1// Czy możemy otworzyć wystawę z Tyranozaurami?
2let pogodaOdpowiednia = true;
3let personelObecny = true;
4let zasilanieStabilne = true;
5let wystarczająceZapasyPożywienia = false;
6let wszystkieDinozauryZdrowe = true;
7
8// Warunek otwarcia: wszystkie czynniki muszą być pozytywne
9let możnaOtworzyćWystawę = pogodaOdpowiednia && personelObecny && zasilanieStabilne &&
10 wystarczająceZapasyPożywienia && wszystkieDinozauryZdrowe;
11console.log(możnaOtworzyćWystawę); // false - brakuje pożywienia
12
13// Warunek alarmu: pogoda zła LUB brak zasilania
14let warunekAlarmu = !pogodaOdpowiednia || !zasilanieStabilne;
15console.log(warunekAlarmu); // false - nie ma powodu do alarmu
16
17// Złożony warunek: jeśli jest personel I (zasilanie ALBO zapasowe generatory)
18let generatoryZapasoweDziałają = true;
19let warunkiOperacyjne = personelObecny && (zasilanieStabilne || generatoryZapasoweDziałają);
20console.log(warunkiOperacyjne); // true - podstawowe warunki są spełnioneKrótkie obwody (short-circuit evaluation)
Operatory && i || wykorzystują technikę "krótkiego obwodu", co oznacza, że drugi warunek może nie być nawet sprawdzany:
1// Przykład z && (AND):
2let systemBezpieczeństwa = false;
3
4function sprawdźStatusDinozaurów() {
5 console.log("Sprawdzanie lokalizacji dinozaurów...");
6 return true;
7}
8
9// Gdy pierwszy warunek jest false, drugi nie jest sprawdzany
10let parkBezpieczny = systemBezpieczeństwa && sprawdźStatusDinozaurów();
11// W konsoli nic się nie pojawi: funkcja nie zostanie wywołana
12
13// Przykład z || (OR):
14let główneZasilanie = true;
15
16function uruchomGeneratory() {
17 console.log("Uruchamianie generatorów...");
18 return true;
19}
20
21// Gdy pierwszy warunek jest true, drugi nie jest sprawdzany
22let zasilanieOperacyjne = główneZasilanie || uruchomGeneratory();
23// W konsoli nic się nie pojawi: funkcja nie zostanie wywołanaWartości prawdziwe i fałszywe (truthy i falsy)
W JavaScript, nie tylko wartości logiczne (true i false) są używane w warunkach. Każda wartość ma swoją "prawdziwość":
Wartości fałszywe (falsy):
false0""(pusty string)nullundefinedNaN
Wszystkie inne wartości są prawdziwe (truthy).
1// Przykłady z Parku Jurajskiego:
2
3// Sprawdzenie, czy dinozaur ma przypisane imię
4let imięDinozaura = ""; // Brak imienia (pusty string)
5if (imięDinozaura) {
6 console.log("Dinozaur ma imię: " + imięDinozaura);
7} else {
8 console.log("Dinozaur nie ma przypisanego imienia"); // To się wykona
9}
10
11// Sprawdzenie, czy identyfikator dinozaura istnieje
12let idDinozaura = 0; // ID 0 (falsy value)
13if (idDinozaura) {
14 console.log("Znaleziono dinozaura o ID: " + idDinozaura);
15} else {
16 console.log("Nie znaleziono prawidłowego ID dinozaura"); // To się wykona
17}
18
19// Sprawdzenie statusu zagrożenia (null oznacza nieznany)
20let poziomZagrożenia = null;
21if (poziomZagrożenia) {
22 console.log("Poziom zagrożenia: " + poziomZagrożenia);
23} else {
24 console.log("Status zagrożenia nieznany"); // To się wykona
25}Operator warunkowy (trójargumentowy)
Operator warunkowy ? : działa jak kompaktowy if...else i jest często używany do przypisań warunkowych:
1// Standardowa konstrukcja if...else
2let statusWybiegu;
3let liczbaRaptorów = 5;
4
5if (liczbaRaptorów > 0) {
6 statusWybiegu = "Zajęty";
7} else {
8 statusWybiegu = "Pusty";
9}
10
11// To samo z operatorem warunkowym
12let statusWybiegu2 = liczbaRaptorów > 0 ? "Zajęty" : "Pusty";
13
14console.log(statusWybiegu); // "Zajęty"
15console.log(statusWybiegu2); // "Zajęty"
16
17// Bardziej złożony przykład - przydzielanie poziomu bezpieczeństwa
18let gatunekDinozaura = "Tyranozaur";
19let poziomBezpieczeństwa = gatunekDinozaura === "Tyranozaur" || gatunekDinozaura === "Spinozaur" ?
20 "Maksymalny" :
21 gatunekDinozaura === "Velociraptor" ?
22 "Wysoki" :
23 "Standardowy";
24
25console.log(`Dla gatunku ${gatunekDinozaura} wymagany poziom bezpieczeństwa: ${poziomBezpieczeństwa}`);
26// "Dla gatunku Tyranozaur wymagany poziom bezpieczeństwa: Maksymalny"Operator łączenia opcjonalnego (optional chaining)
W nowszych wersjach JavaScript dostępny jest operator łączenia opcjonalnego ?., który bezpiecznie sprawdza, czy właściwość obiektu istnieje przed próbą dostępu do niej:
1// Struktura danych dinozaura
2let tyranozaur = {
3 nazwa: "Rex",
4 statystyki: {
5 wiek: 8,
6 waga: 8000,
7 dieta: "mięsożerna"
8 }
9};
10
11let triceratops = {
12 nazwa: "Tricy",
13 // brak statystyk
14};
15
16// Bezpieczne odczytywanie zagnieżdżonych właściwości
17console.log(tyranozaur.statystyki?.waga); // 8000
18console.log(triceratops.statystyki?.waga); // undefined, bez błędu
19
20// Bez optional chaining dostalibyśmy błąd:
21// console.log(triceratops.statystyki.waga); // Error: Cannot read property 'waga' of undefinedOperator łączenia null (nullish coalescing)
Operator ?? zwraca prawy operand, gdy lewy jest null lub undefined, inaczej zwraca lewy operand:
1// Ustawienie domyślnych wartości dla brakujących danych
2let raportBezpieczeństwa = {
3 zagrożenie: 0,
4 // brak statusu zasilania
5};
6
7// Używamy ?? aby zapewnić wartość domyślną gdy właściwość jest null lub undefined
8let poziomZagrożenia = raportBezpieczeństwa.zagrożenie ?? "Nieznany";
9let statusZasilania = raportBezpieczeństwa.zasilanie ?? "Nieokreślony";
10
11console.log(poziomZagrożenia); // 0 (wartość 0 nie jest null ani undefined, więc zostaje zwrócona)
12console.log(statusZasilania); // "Nieokreślony" (właściwość nie istnieje, więc przyjęto wartość domyślną)
13
14// Porównanie z || (OR)
15let poziomZagrożeniaOr = raportBezpieczeństwa.zagrożenie || "Nieznany";
16console.log(poziomZagrożeniaOr); // "Nieznany" (0 jest falsy, więc zwrócono wartość domyślną)Podsumowanie
Operatory porównania i logiczne w JavaScript, podobnie jak systemy decyzyjne w Parku Jurajskim, pozwalają na:
- Porównywanie wartości i typów (==, ===, !=, !==, >, <, >=, <=)
- Łączenie warunków (&&, ||, !)
- Tworzenie kompaktowych wyrażeń warunkowych (? :)
- Bezpieczne dostępy do właściwości obiektów (?.)
- Zapewnienie wartości domyślnych dla null/undefined (??)
Dzięki tym operatorom możemy tworzyć inteligentne systemy decyzyjne, które reagują na różne warunki - podobnie jak systemy bezpieczeństwa Parku Jurajskiego muszą reagować na zmieniające się okoliczności, aby utrzymać kontrolę nad parkiem pełnym niebezpiecznych dinozaurów.
W następnej lekcji przyjrzymy się priorytetowi operatorów, czyli temu, w jakiej kolejności JavaScript wykonuje działania w złożonych wyrażeniach.
Kod do tej lekcji: index.js
1// Operatory porównania i logiczne
2// System bezpieczeństwa Parku Jurajskiego
3
4// === Operatory porównania ===
5console.log("=== Operatory porównania ===");
6
7let napiecie = 10000;
8let minimum = 8000;
9
10console.log("napięcie > minimum:", napiecie > minimum); // true
11console.log("napięcie < minimum:", napiecie < minimum); // false
12console.log("napięcie >= 10000:", napiecie >= 10000); // true
13console.log("napięcie <= 5000:", napiecie <= 5000); // false
14
15// == vs === (równość vs ścisła równość)
16console.log("\n=== == vs === ===");
17console.log("5 == '5':", 5 == '5'); // true (porównuje wartości)
18console.log("5 === '5':", 5 === '5'); // false (porównuje wartości I typy)
19console.log("null == undefined:", null == undefined); // true
20console.log("null === undefined:", null === undefined); // false
21
22// != vs !==
23console.log("5 != '5':", 5 != '5'); // false
24console.log("5 !== '5':", 5 !== '5'); // true
25
26// === Operatory logiczne ===
27console.log("\n=== Operatory logiczne ===");
28
29let ogrodzenieAktywne = true;
30let personelBezpieczny = true;
31let burzaNadchodzi = false;
32
33// AND (&&) - oba warunki muszą być true
34console.log("Można otworzyć park:", ogrodzenieAktywne && personelBezpieczny);
35
36// OR (||) - wystarczy jeden warunek true
37console.log("Wymaga uwagi:", !ogrodzenieAktywne || burzaNadchodzi);
38
39// NOT (!) - negacja
40console.log("Ogrodzenie nieaktywne:", !ogrodzenieAktywne);
41
42// Łączenie operatorów
43let moznaOtworzyc = ogrodzenieAktywne && personelBezpieczny && !burzaNadchodzi;
44console.log("\nDecyzja o otwarciu:", moznaOtworzyc);
45
46// Twoje zadanie:
47// 1. Sprawdź różnice między == a ===
48// 2. Połącz kilka warunków operatorami && i ||
49Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Co zwróci porównanie 5 === '5' w JavaScript?
2. Kiedy operator logiczny && (AND) zwraca true?
Zadania praktyczne w grze
- Klikanie w kolejności
Ułóż wyrażenie, które sprawdza, czy dinoCount jest ściśle równe expectedCount (zmienne w tej kolejności):