Kurs JavaScript i TypeScript · Moduł 1: Podstawy JavaScript

Operatory porównania i logiczne

8 min czytania
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 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;
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ł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}

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 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ę 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 ||
49

Widzisz błąd w tej lekcji?

Sprawdź się

Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.

  1. 1. Co zwróci porównanie 5 === '5' w JavaScript?

  2. 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):

Przydatne artykuły