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 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 maksimumW 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 danych1// 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)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ęciW 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 otwarcieW 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łnioneOperatory && 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;
3let wszystkieDinozauryWZagrodach = sprawdźStatusDinozaurów(); // Ta funkcja nie zostanie wywołana!
4
5function sprawdźStatusDinozaurów() {
6 console.log("Sprawdzanie lokalizacji dinozaurów...");
7 return true;
8}
9
10// Gdy pierwszy warunek jest false, drugi nie jest sprawdzany
11let parkBezpieczny = systemBezpieczeństwa && wszystkieDinozauryWZagrodach;
12// W konsoli nic się nie pojawi, funkcja nigdy nie zostanie wywołana
13
14// Przykład z || (OR):
15let główneZasilanie = true;
16let zapaloweGeneratory = uruchomGeneratory(); // Ta funkcja nie zostanie wywołana!
17
18function uruchomGeneratory() {
19 console.log("Uruchamianie generatorów...");
20 return true;
21}
22
23// Gdy pierwszy warunek jest true, drugi nie jest sprawdzany
24let zasilanieOperacyjne = główneZasilanie || zapaloweGeneratory;
25// W konsoli nic się nie pojawi, funkcja nigdy nie zostanie wywołanaW 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)nullundefinedNaNWszystkie 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
? : 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"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
?? 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ą)Operatory porównania i logiczne w JavaScript, podobnie jak systemy decyzyjne w Parku Jurajskim, pozwalają na:
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ę pętlom, które pozwalają na wielokrotne wykonywanie kodu - co jest niezbędne np. przy monitorowaniu wielu wybiegów dla dinozaurów jednocześnie.