Utilizziamo i cookie per migliorare la tua esperienza sul sito
CodeWorlds

Operatory porównania i logiczne

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 maksimum

Róż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ęci

Operatory 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 otwarcie

Zł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łnione

Kró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;
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łana

Wartoś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):

  • false
  • 0
  • ""
    (pusty string)
  • null
  • undefined
  • NaN

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}

Operatory warunkowe (trójargumentowe)

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 undefined

Operator łą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ę pętlom, które pozwalają na wielokrotne wykonywanie kodu - co jest niezbędne np. przy monitorowaniu wielu wybiegów dla dinozaurów jednocześnie.

Vai a CodeWorlds