Instrukcja if / else
Do tej pory program wykonywał wszystkie linie po kolei, od góry do dołu. Teraz nauczy się podejmować decyzje: wykonać jeden fragment kodu, a inny pominąć — w zależności od danych.
Czego się dziś nauczysz
- Zapiszesz decyzję programu instrukcją
ifz blokiemelse - Zbudujesz drabinkę
else ifi ustawisz warunki we właściwej kolejności - Wyjaśnisz, dlaczego zmienna zadeklarowana w bloku nie istnieje poza nim
- Zastąpisz zagnieżdżone
ifwcześniejszym wyjściem lub złożonym warunkiem - Rozpoznasz, kiedy zamiast
iflepszy jest operator warunkowy
Instrukcja if
if (warunek) {
// wykona się tylko wtedy, gdy warunek jest prawdziwy
}
┌──────────────┐
│ warunek? │
└──────┬───────┘
prawda │ fałsz
┌───────┴────────┐
▼ │
┌─────────┐ │
│ blok │ │
└────┬────┘ │
└────────┬───────┘
▼
dalsza część programu
const punkty = 62;
if (punkty >= 50) {
console.log("Egzamin zdany");
}
if (punkty >= 90) {
console.log("Wynik celujący"); // nie wykona się
}
console.log("Koniec sprawdzania"); // wykona się zawsze
W nawiasie po if stoi wyrażenie logiczne — takie jak te z lekcji 4. Może to być
porównanie, zmienna typu boolean albo cały złożony warunek z &&
i ||.
const wiek = 17;
const maZgode = true;
const oceny = [5, 4, 3];
if (wiek >= 18) { } // porównanie
if (maZgode) { } // zmienna logiczna
if (!maZgode) { } // zaprzeczenie
if (wiek >= 16 && maZgode) { } // warunek złożony
if (oceny.length > 0) { } // wynik obliczenia
if (oceny.includes(1)) { } // wynik metody
Zmienna logiczna nie potrzebuje porównania
Zapis if (maZgode === true) działa, ale jest nadmiarowy — maZgode
już jest prawdą albo fałszem. Pisz po prostu if (maZgode) oraz
if (!maZgode). Dobrze dobrana nazwa zmiennej (czy…, ma…,
jest…) sprawia, że warunek czyta się jak zdanie.
else i else if
Blok else wykonuje się wtedy, gdy warunek był fałszywy. Wykona się dokładnie
jedna z dwóch gałęzi — nigdy obie, nigdy żadna:
const temperatura = 3;
if (temperatura > 0) {
console.log("Powyżej zera");
} else {
console.log("Mróz");
}
Gdy możliwości jest więcej, dokładamy kolejne warunki przez else if.
Program sprawdza je po kolei i zatrzymuje się na pierwszym prawdziwym:
const procent = 74;
let ocena: string;
if (procent >= 90) {
ocena = "celujący";
} else if (procent >= 75) {
ocena = "bardzo dobry";
} else if (procent >= 60) {
ocena = "dobry";
} else if (procent >= 50) {
ocena = "dostateczny";
} else {
ocena = "niedostateczny";
}
console.log(`${procent}% → ${ocena}`); // 74% → dobry
Dlaczego nie trzeba pisać procent >= 60 && procent < 75
Bo do trzeciego warunku program dociera tylko wtedy, gdy dwa poprzednie były fałszywe —
czyli gdy procent jest już na pewno mniejszy niż 75. Drabinka else if sama
odcina górne przedziały. Dopisywanie drugiego porównania to zbędna praca i okazja do pomyłki.
Kolejność warunków decyduje o wyniku
Ten sam zestaw warunków w złej kolejności daje bezsensowne wyniki:
const procent = 95;
if (procent >= 50) {
console.log("dostateczny"); // ← program zatrzyma się TUTAJ
} else if (procent >= 75) {
console.log("bardzo dobry"); // nigdy nieosiągalne
} else if (procent >= 90) {
console.log("celujący"); // nigdy nieosiągalne
}
Wynik: dostateczny — mimo 95 punktów. Warunek procent >= 50 jest
prawdziwy także dla 95, a program nie sprawdza już nic dalej.
Reguła
Przy progach liczbowych układaj warunki od najbardziej szczegółowego do najbardziej
ogólnego — zwykle od największej wartości w dół. Ostatni else łapie
wszystko, co nie pasowało wcześniej.
Zagnieżdżanie i zasięg zmiennych
Wewnątrz bloku if może stać kolejny if. Bywa to potrzebne, ale szybko
robi się nieczytelne:
const zalogowany = true;
const maUprawnienia = true;
const dokumentIstnieje = true;
if (zalogowany) {
if (maUprawnienia) {
if (dokumentIstnieje) {
console.log("Otwieram dokument");
} else {
console.log("Brak dokumentu");
}
} else {
console.log("Brak uprawnień");
}
} else {
console.log("Zaloguj się");
}
const zalogowany = true;
const maUprawnienia = true;
const dokumentIstnieje = true;
if (!zalogowany) {
console.log("Zaloguj się");
} else if (!maUprawnienia) {
console.log("Brak uprawnień");
} else if (!dokumentIstnieje) {
console.log("Brak dokumentu");
} else {
console.log("Otwieram dokument");
}
Ta technika nazywa się strażnikami (ang. guard clauses): najpierw odrzucasz
po kolei wszystkie przypadki błędne, a właściwe działanie zostaje na końcu, na płaskim poziomie.
W funkcjach (lekcja 11) będzie jeszcze wygodniej, bo zamiast else if użyjesz
return.
Zasięg blokowy
const punkty = 80;
if (punkty >= 50) {
const komentarz = "gratulacje";
console.log(komentarz); // OK — jesteśmy w tym samym bloku
}
console.log(komentarz); // Błąd TS2304: Cannot find name 'komentarz'.
Zmienna zadeklarowana przez let lub const wewnątrz nawiasów klamrowych
żyje tylko do końca tego bloku. Jeśli wynik ma być widoczny dalej, zadeklaruj zmienną
przed instrukcją if:
const punkty = 80;
let komentarz: string;
if (punkty >= 50) {
komentarz = "gratulacje";
} else {
komentarz = "spróbuj ponownie";
}
console.log(komentarz); // OK
Kompilator pilnuje, żeby zmienna została ustawiona
Gdybyś pominął blok else, TypeScript zgłosi TS2454: Variable 'komentarz'
is used before being assigned — bo istnieje droga przez program, na której zmienna
nigdy nie dostała wartości. To jedna z tych rzeczy, których zwykły JavaScript nie sprawdza.
Skróty zapisu
Gdy blok ma jedną instrukcję, klamry można pominąć — ale rób to ostrożnie:
let punkty = -2;
// dopuszczalne przy krótkim, jednolinijkowym warunku
if (punkty < 0) punkty = 0;
// PUŁAPKA — druga linia wykona się ZAWSZE, mimo wcięcia
if (punkty < 0)
console.log("Wartość ujemna");
console.log("Poprawiam na zero"); // to już nie należy do if!
Zasada bezpieczeństwa
Wcięcie nie ma dla kompilatora żadnego znaczenia — liczą się tylko klamry. W tym kursie zawsze piszemy klamry, nawet przy jednej instrukcji. Kosztuje to dwa znaki, a oszczędza godzinę szukania błędu.
Kiedy zamiast if użyć operatora warunkowego
const zdany = true;
function wyslijCertyfikat(): void { console.log("Symulacja wydania certyfikatu"); }
function zapiszNaPoprawke(): void { console.log("Symulacja zapisu na poprawkę"); }
// wybór jednej z dwóch wartości — operator warunkowy jest krótszy
const status = zdany ? "ZDANY" : "NIEZDANY";
// wykonanie różnych działań — tu potrzebny jest if
if (zdany) {
console.log("Gratulacje!");
wyslijCertyfikat();
} else {
console.log("Zapraszamy na poprawkę");
zapiszNaPoprawke();
}
Reguła jest prosta: operator warunkowy wybiera wartość, instrukcja if
wybiera działanie.
Umowne dane ćwiczenia
Ocena szkolna wyliczona ze średniej oraz maksymalne liczby punktów są założeniami tego przykładu, nie oficjalnym sposobem wystawiania wyniku egzaminu. Uczymy się warunków. W zadaniu o haśle test cyfry dla pojedynczego znaku ASCII zapisuj jako znak >= "0" && znak <= "9"; Number zamienia także część białych znaków na zero.
Kalkulator oceny z egzaminu zawodowego
Program sprawdza poprawność danych, przelicza punkty na procenty, ustala ocenę według progów i dodaje komentarz zależny od kilku warunków naraz.
// ── dane wejściowe ──
const uczen = "Marta Kowalska";
const punktyPisemny = 32;
const maksPisemny = 40;
const punktyPraktyczny = 17;
const maksPraktyczny = 20;
const obecnyNaObu = true;
const PROG_PISEMNY = 50;
const PROG_PRAKTYCZNY = 75;
console.log(`Wyniki: ${uczen}`);
console.log("─".repeat(40));
// ── 1. Strażnicy: odrzucamy dane bezsensowne ──
if (!obecnyNaObu) {
console.log("Uczeń nieobecny na jednej z części — egzamin niezaliczony.");
} else if (punktyPisemny < 0 || punktyPisemny > maksPisemny) {
console.log("Błąd danych: punkty z części pisemnej poza zakresem.");
} else if (punktyPraktyczny < 0 || punktyPraktyczny > maksPraktyczny) {
console.log("Błąd danych: punkty z części praktycznej poza zakresem.");
} else {
// ── 2. Obliczenia ──
const procentPisemny = (punktyPisemny / maksPisemny) * 100;
const procentPraktyczny = (punktyPraktyczny / maksPraktyczny) * 100;
const zdanyPisemny = procentPisemny >= PROG_PISEMNY;
const zdanyPraktyczny = procentPraktyczny >= PROG_PRAKTYCZNY;
const zdanyCaly = zdanyPisemny && zdanyPraktyczny;
console.log(`Pisemna: ${procentPisemny.toFixed(1)}% (próg ${PROG_PISEMNY}%) ${zdanyPisemny ? "zdana" : "niezdana"}`);
console.log(`Praktyczna: ${procentPraktyczny.toFixed(1)}% (próg ${PROG_PRAKTYCZNY}%) ${zdanyPraktyczny ? "zdana" : "niezdana"}`);
// ── 3. Ocena według progów ──
const sredni = (procentPisemny + procentPraktyczny) / 2;
let ocena: number;
if (sredni >= 91) {
ocena = 6;
} else if (sredni >= 81) {
ocena = 5;
} else if (sredni >= 71) {
ocena = 4;
} else if (sredni >= 51) {
ocena = 3;
} else if (sredni >= 31) {
ocena = 2;
} else {
ocena = 1;
}
console.log("─".repeat(40));
console.log(`Średni wynik: ${sredni.toFixed(1)}%`);
console.log(`Ocena: ${ocena}`);
console.log(`Kwalifikacja: ${zdanyCaly ? "ZDANA" : "NIEZDANA"}`);
// ── 4. Komentarz ──
if (zdanyCaly && sredni >= 90) {
console.log("Znakomity wynik — gratulacje!");
} else if (zdanyCaly) {
console.log("Kwalifikacja zdana, jest jeszcze pole do poprawy.");
} else if (zdanyPisemny && !zdanyPraktyczny) {
console.log("Do poprawy tylko część praktyczna.");
} else if (!zdanyPisemny && zdanyPraktyczny) {
console.log("Do poprawy tylko część pisemna.");
} else {
console.log("Do poprawy obie części.");
}
}
Wyniki: Marta Kowalska
────────────────────────────────────────
Pisemna: 80.0% (próg 50%) zdana
Praktyczna: 85.0% (próg 75%) zdana
────────────────────────────────────────
Średni wynik: 82.5%
Ocena: 5
Kwalifikacja: ZDANA
Kwalifikacja zdana, jest jeszcze pole do poprawy.
Trzy rzeczy warte podpatrzenia
| Technika | Na czym polega |
|---|---|
| Strażnicy na początku | Wstępne warunki odrzucają błędy przewidziane w przykładzie. W pełnej walidacji trzeba również sprawdzić skończoność liczb, dopuszczalne wartości maksymalne i reguły punktacji. |
| Warunki w nazwanych zmiennych | zdanyPisemny i zdanyPraktyczny liczymy raz, a używamy
w czterech miejscach. Zmiana progu wymaga poprawki w jednej linii. |
Deklaracja let ocena: number; przed drabinką |
Zmienna musi przeżyć wyjście z bloków if. Ostatni else
gwarantuje, że zawsze dostanie wartość — inaczej kompilator zgłosiłby TS2454. |
Sprawdź to sam
Zmień punktyPraktyczny na 10 i uruchom ponownie — zobaczysz komunikat
o poprawce z części praktycznej. Potem ustaw obecnyNaObu na false
i zwróć uwagę, że żadne obliczenie się nie wykona.
Na co uważać
| Kod | Problem |
|---|---|
if (x = 5) |
Jeden znak równości to przypisanie, nie porównanie. Ma być ===.
TypeScript zgłosi błąd, JavaScript wykonałby to bez słowa. |
if (punkty >= 50); |
Średnik zaraz po nawiasie kończy instrukcję — blok poniżej wykona się zawsze. |
if (a < b < c) |
Nie da się porównać trzech wartości naraz. Ma być a < b && b < c. |
if (ocena === 5 || 6) |
Prawa strona to samo 6, czyli zawsze prawda. Ma być
ocena === 5 || ocena === 6. |
if (liczbaPunktow) przy 0 punktach |
Zero jest wartością fałszywą, więc warunek nie zadziała. Pisz
if (liczbaPunktow !== undefined). |
Drabinka bez else |
Gdy zmienna ma dostać wartość w każdej gałęzi, brak else to
TS2454 — i słusznie. |
Zadania
const x = 10;
if (x > 5) {
console.log("A");
} else if (x > 8) {
console.log("B");
}
if (x > 5) {
console.log("C");
}
if (x > 8) {
console.log("D");
}
pokaż rozwiązanie
A
C
D
W pierwszej konstrukcji B jest nieosiągalne — else if sprawdza się
tylko wtedy, gdy poprzedni warunek był fałszywy. W drugiej mamy dwie niezależne
instrukcje if, więc obie się wykonują. To najważniejsza różnica między
drabinką else if a osobnymi warunkami.
Rozbuduj kalkulator BMI z lekcji 3: po obliczeniu wskaźnika wypisz kategorię według progów —
poniżej 18,5 niedowaga, do 24,9 waga prawidłowa, do 29,9 nadwaga,
powyżej otyłość. Użyj drabinki else if.
Bilet do kina kosztuje 28 zł. Zastosuj zniżki: dzieci do 6 lat wchodzą za darmo, uczniowie i studenci do 26 lat płacą 60% ceny, seniorzy od 65 lat płacą połowę. We wtorki wszyscy (poza dziećmi) dostają dodatkowe 5 zł zniżki, ale cena nie może spaść poniżej 10 zł. Wypisz wiek, dzień, zastosowaną zniżkę i kwotę do zapłaty.
pokaż przykładowe rozwiązanie
const CENA_PODSTAWOWA = 28;
const MIN_CENA = 10;
const wiek = 17;
const uczen = true;
const wtorek = true;
let cena: number;
let rodzajZnizki: string;
if (wiek < 6) {
cena = 0;
rodzajZnizki = "wstęp bezpłatny";
} else if (uczen && wiek <= 26) {
cena = CENA_PODSTAWOWA * 0.6;
rodzajZnizki = "uczniowska";
} else if (wiek >= 65) {
cena = CENA_PODSTAWOWA * 0.5;
rodzajZnizki = "senior";
} else {
cena = CENA_PODSTAWOWA;
rodzajZnizki = "brak";
}
if (wtorek && cena > 0) {
cena = cena - 5;
if (cena < MIN_CENA) {
cena = MIN_CENA;
}
rodzajZnizki += " + wtorek";
}
console.log(`Wiek: ${wiek}`);
console.log(`Zniżka: ${rodzajZnizki}`);
console.log(`Do zapłaty: ${cena.toFixed(2)} zł`);
Zwróć uwagę na kolejność: najpierw ustalamy zniżkę podstawową w drabince (jedna z czterech), a dopiero potem, osobną instrukcją, doliczamy promocję wtorkową. To dwie niezależne decyzje, więc nie mogą być w jednej drabince.
Sprawdź hasło zapisane w zmiennej i wypisz wszystkie niespełnione wymagania (nie tylko pierwsze): co najmniej 8 znaków, zawiera cyfrę, zawiera wielką literę, nie zawiera spacji. Na końcu wypisz ocenę siły hasła: słabe (0–1 spełnionych), średnie (2–3), mocne (4). Podpowiedź: zlicz spełnione wymagania w zmiennej.
pokaż wskazówki
Przejdź znaki pętlą. Cyfrę ASCII sprawdź przez znak >= "0" && znak <= "9". Wielką literę rozpoznaj przez znak === znak.toUpperCase() && znak !== znak.toLowerCase(). haslo.includes(" ") wykrywa zwykłą spację. To ćwiczenie warunków, nie kompletna ocena bezpieczeństwa hasła.
Napisz program liczący koszt wyjazdu klasowego. Dane: liczba uczniów, liczba nauczycieli,
odległość w kilometrach, liczba noclegów. Zasady: autokar kosztuje 4,20 zł za kilometr, przy
dystansie powyżej 300 km doliczana jest dieta kierowcy 250 zł. Nocleg to 90 zł od osoby,
nauczyciele nocują bezpłatnie. Przy grupie 40 osób i większej cena noclegu spada do 80 zł.
Wypisz rozbicie kosztów i kwotę przypadającą na jednego ucznia (zaokrągloną w górę
do pełnych złotych — Math.ceil). Zadbaj o strażników: liczba uczniów musi być
dodatnia, a nauczycieli co najmniej jeden.
pokaż szkielet rozwiązania
const uczniowie = 28;
const nauczyciele = 2;
const kilometry = 340;
const noclegi = 2;
if (uczniowie <= 0) {
console.log("Błąd: brak uczniów.");
} else if (nauczyciele < 1) {
console.log("Błąd: wymagany co najmniej jeden opiekun.");
} else {
const osoby = uczniowie + nauczyciele;
let kosztAutokaru = kilometry * 2 * 4.2; // w obie strony
if (kilometry > 300) {
kosztAutokaru += 250;
}
const cenaNoclegu = osoby >= 40 ? 80 : 90;
const kosztNoclegow = uczniowie * noclegi * cenaNoclegu;
const razem = kosztAutokaru + kosztNoclegow;
const naUcznia = Math.ceil(razem / uczniowie);
console.log(`Autokar: ${kosztAutokaru.toFixed(2)} zł`);
console.log(`Noclegi: ${kosztNoclegow.toFixed(2)} zł`);
console.log(`Razem: ${razem.toFixed(2)} zł`);
console.log(`Na ucznia: ${naUcznia} zł`);
}
Co trzeba zapamiętać
- Drabinka
else ifwykonuje dokładnie jedną gałąź — pierwszą pasującą. - Osobne instrukcje
ifsą niezależne i mogą wykonać się wszystkie. - Przy progach liczbowych układaj warunki od najwyższego w dół.
- Zmienna z
let/constżyje tylko w swoim bloku klamrowym. - Zagnieżdżenia zastępuj strażnikami — najpierw odrzuć przypadki błędne.
- Klamry piszemy zawsze, nawet przy jednej instrukcji.
- Operator
? :wybiera wartość,ifwybiera działanie.