Instrukcje warunkowe if, else if i switch oraz pętle for, while, do...while, for...of i for...in w języku JavaScript: kiedy sprawdzany jest warunek, ile obrotów wykona pętla, co robią break i continue oraz jak pętla buduje listę HTML. Lekcja 11.3 kursu INF.03.
Instrukcja sterująca to konstrukcja języka, która decyduje, CZY i ILE RAZY wykona się fragment kodu: warunek wybiera jedną z dróg, a pętla powtarza ten sam blok. Bez nich skrypt idzie od góry do dołu i przy każdym wczytaniu strony robi dokładnie to samo. W części pisemnej wracają pytania z ramką kodu („ile razy wykona się przedstawiona pętla", „które wartości zostaną kolejno wypisane", „która pętla wykona się co najmniej raz", „jak zapisać warunek na przedział od 10 do 100"). W zadaniu praktycznym if sprawdza wartość wpisaną w pole formularza, a pętla przechodzi po tablicy i buduje z niej listę widoczną na stronie sklepu.
Warunek: if, else if, else
if (JEŻELI) to instrukcja wykonująca blok w nawiasach klamrowych tylko wtedy, gdy warunek w nawiasach okrągłych jest prawdziwy. else (W PRZECIWNYM RAZIE) dokłada drugą drogę, na którą skrypt wchodzi przy warunku niespełnionym, a else if (A JEŻELI) wstawia między nie kolejne pytanie. Warunki sprawdzane są po kolei, od góry: pierwszy prawdziwy wygrywa, reszta zostaje pominięta. W JavaScripcie te dwa słowa pisze się osobno, bo elseif znane z PHP jest tu błędem składni.
const kwota = 250;
let rabat;
if (kwota >= 500) {
rabat = 10;
} else if (kwota >= 200) {
rabat = 5;
} else {
rabat = 0;
}
console.log("Rabat: " + rabat + " procent");
Wynik: Rabat: 5 procent. Kwota 250 nie przeszła pierwszego warunku, przeszła drugi, więc else nie ma już nic do roboty. Klamry przy jednej instrukcji wolno pominąć, ale do warunku należy wtedy wyłącznie NAJBLIŻSZA instrukcja, a wcięcie kolejnego wiersza niczego nie zmienia.
Warunek złożony łączy kilka porównań operatorami logicznymi: && (I) wymaga obu części, || (LUB) wystarczy jedna, ! (NIE) odwraca wynik. Przedział domknięty z dwóch stron powstaje zawsze przez &&.
const liczba = 150;
if (liczba > 100 && liczba <= 200) {
console.log("w przedziale");
} else {
console.log("poza przedziałem");
}
Wynik: w przedziale, bo liczba spełnia oba porównania naraz. Ten sam zapis z || byłby prawdziwy dla każdej liczby, bo każda jest albo większa od 100, albo mniejsza lub równa 200.
Osobna pułapka mieszka w jednym znaku. Przypisanie postawione w miejscu porównania nie zgłasza błędu, tylko po cichu zmienia zmienną i oddaje przypisaną wartość jako wynik warunku.
let x = 3;
if (x = 5) {
console.log("warunek spełniony, x wynosi " + x);
}
Wynik: warunek spełniony, x wynosi 5, choć zmienna miała trójkę i niczego z niczym nie porównano. Gdyby x była stałą const, ta sama linia zatrzymałaby skrypt błędem przypisania do stałej.
Pułapka: = przypisuje wartość, == porównuje same wartości, a === wartość i typ. Różnicę między == a === opisuje lekcja o zmiennych i operatorach. switch, case, default i przelot
switch (PRZEŁĄCZ) to instrukcja wyboru, która porównuje JEDNĄ wartość z listą przypadków case (PRZYPADEK) i wykonuje kod od pierwszego pasującego. Zastępuje długi łańcuch else if o wciąż tej samej zmiennej. break (PRZERWIJ) kończy całą instrukcję, a default (DOMYŚLNY) łapie wartości spoza listy. Porównanie działa jak ===, więc case "5" nie złapie liczby 5.
const sposob = "paczkomat";
switch (sposob) {
case "kurier":
console.log("Dostawa: 15 zł");
break;
case "paczkomat":
console.log("Dostawa: 10 zł");
break;
default:
console.log("Odbiór osobisty");
}
Wynik: Dostawa: 10 zł. Zapomniany break daje przelot, czyli wykonanie także kolejnych przypadków, i to bez sprawdzania ich wartości.
const sposob = "kurier";
let cena = 0;
switch (sposob) {
case "kurier":
cena += 15;
case "paczkomat":
cena += 10;
default:
cena += 1;
}
console.log(cena);
Wynik: 26, bo po trafieniu w pierwszy przypadek skrypt przeszedł przez wszystkie pozostałe. Z break po każdym case wynikiem byłoby 15. Dwa przypadki postawione jeden pod drugim, bez kodu między nimi, to ten sam przelot użyty celowo: obie wartości prowadzą do jednego bloku.
Pętle: for, while i do...while
Pętla to instrukcja powtarzająca ten sam blok kodu, dopóki jej warunek jest prawdziwy. Jedno wykonanie bloku to obrót, inaczej iteracja, i to jego liczby dotyczy większość pytań z banku.
for (DLA) trzyma w nawiasie trzy części rozdzielone średnikami: wartość początkową licznika, warunek trwania pętli i krok wykonywany po każdym obrocie. Nadaje się tam, gdzie liczba powtórzeń jest znana z góry.
for (let i = 2; i <= 12; i += 2) {
console.log(i);
}
Wynik: sześć wierszy z liczbami 2, 4, 6, 8, 10, 12. Licznik deklaruje słowo let (NIECH), które zamyka go w samej pętli; w arkuszach i w bankach pytań stoi tam starsze var, widoczne w całej funkcji, ale w takiej pętli działające tak samo.
while (DOPÓKI) sprawdza warunek PRZED każdym obrotem, więc przy warunku fałszywym od początku blok nie wykona się ani razu. Pasuje tam, gdzie liczby powtórzeń nie znamy z góry.
Wynik: trzy wiersze, od zostało sztuk: 3 do zostało sztuk: 1.
do...while (WYKONUJ DOPÓKI) sprawdza warunek na KOŃCU obrotu, więc blok wykonuje się co najmniej raz, nawet gdy warunek jest fałszywy od początku. Po zamykającym nawiasie stoi średnik.
let i = 1;
do {
console.log(i);
i++;
} while (i > 5);
Wynik: 1, jeden obrót mimo fałszywego warunku.
Pętla
Kiedy sprawdza warunek
Minimum wykonań
Do czego
for
przed obrotem
0
znana z góry liczba powtórzeń, licznik
while
przed obrotem
0
powtarzanie do skutku, nieznana liczba obrotów
do...while
po obrocie
1
gdy blok ma wykonać się choć raz
for...of
przed obrotem
0
wartości tablicy
for...in
przed obrotem
0
indeksy tablicy, klucze obiektu
for...of, for...in oraz break i continue
for...of (DLA KAŻDEGO Z) to pętla przechodząca po WARTOŚCIACH tablicy, bez licznika i bez sprawdzania jej długości. for...in (DLA KAŻDEGO W) chodzi po INDEKSACH tablicy oraz kluczach obiektu, więc w każdym obrocie oddaje numer miejsca, a nie to, co w nim leży.
const produkty = ["Klawiatura", "Mysz", "Monitor 24"];
for (const nazwa of produkty) {
console.log(nazwa);
}
for (const indeks in produkty) {
console.log(indeks + ": " + produkty[indeks]);
}
Klawiatura
Mysz
Monitor 24
0: Klawiatura
1: Mysz
2: Monitor 24
Biegiem każdej pętli sterują dwa słowa. break przerywa całą pętlę i przenosi wykonanie za jej klamrę, a continue (KONTYNUUJ) przerywa tylko bieżący obrót i przechodzi do następnego.
const ceny = [30, 0, 45, 120];
let suma = 0;
for (const cena of ceny) {
if (cena === 0) {
continue;
}
if (cena > 100) {
break;
}
suma += cena;
}
console.log(suma);
Wynik: 75. Zero zostało pominięte przez continue, po czym doszły 30 i 45, a cena 120 wywołała break, więc pętla skończyła się przed dodaniem czegokolwiek więcej.
Pętla nieskończona to taka, której warunek nigdy nie staje się fałszywy: while (true) albo while (i < 10) z zapomnianym zwiększaniem i. Wychodzi się z niej przez break, a bez tego przeglądarka blokuje kartę aż do zamknięcia strony.
Ile obrotów wykona pętla
Pytanie o liczbę iteracji rozwiązuje się zawsze tak samo: wypisz licznik na wejściu, sprawdź warunek, dopisz krok i powtarzaj do pierwszego fałszu. Ten sam rachunek pokaże krok po kroku interpreter JavaScript w przeglądarce. let i = 0;
let obroty = 0;
while (i < 10) {
i += 3;
obroty++;
}
console.log(i + " " + obroty);
Obrót
i na wejściu
Warunek i < 10
i po kroku
Wynik: 12 4, czyli cztery obroty i licznik zatrzymany na 12. Pętla for z warunkiem i < n i krokiem i++ wykonuje dokładnie n obrotów, a licznik przyjmuje wartości od 0 do n - 1. Ta sama pętla z warunkiem i <= n ma o jeden obrót więcej i właśnie tym jednym obrotem różnią się zwykle odpowiedzi w pytaniu.
Wynik: 600. Licznik przyjmuje 25 wartości parzystych od 0 do 48, więc zmienna w niesie sumę liczb parzystych mniejszych od 50, a nie ich liczbę.
Lista generowana w pętli
Pętla sklejająca znaczniki w jeden napis to najczęstsze zadanie skryptu na stronie: wchodzi tablica z danymi, wychodzi gotowy kawałek HTML. Napis rośnie operatorem +=, po jednym elemencie na obrót.
const produkty = ["Klawiatura", "Mysz", "Monitor 24"];
let lista = "";
for (const nazwa of produkty) {
lista += "<li>" + nazwa + "</li>";
}
console.log(lista);
<li>Klawiatura</li><li>Mysz</li><li>Monitor 24</li>
Ten napis trafia na stronę jednym przypisaniem do własności innerHTML (wnętrze elementu): document.getElementById("lista").innerHTML = lista; zamienia całą zawartość pustego <ul id="lista"> na trzy pozycje listy. Pobieranie elementów opisuje lekcja o modelu DOM, a same tablice lekcja o tablicach i obiektach. Własność innerHTML wstawia napis jako KOD, więc znaczniki w nim ożywają, i dlatego nie wkłada się tam surowego tekstu od użytkownika: do samego tekstu służy textContent. Starsze document.write, obecne w wielu pytaniach z banku, dopisuje wynik wprost do dokumentu w trakcie jego wczytywania, ale wywołane po załadowaniu strony kasuje całą jej treść, więc w prawdziwym skrypcie zostaje innerHTML.
Na egzaminie
Pytania pisemne o instrukcje sterujące mają kilka stałych kształtów. Ramka z pętlą i pytanie o liczbę wykonań albo o kolejno wypisywane wartości: wypisz wartości licznika po kolei, pamiętając, że warunek ze znakiem < daje o jeden obrót mniej niż ten sam warunek ze znakiem <=. Polecenie „wskaż pętlę, która wyświetli sześć kolejnych liczb parzystych": licznik startuje od 2, krok to i += 2, a granica musi być domknięta, czyli i <= 12. Zapis warunku na przedział: przedział domknięty z dwóch stron wymaga &&, a „przynajmniej jeden z dwóch przypadków" to || między grupami, z && w środku każdej z nich. Pętla wykonująca się co najmniej raz to do...while, a pętla po wszystkich wartościach tablicy bez licznika to for...of. Osobny kształt to szukanie błędu w gotowym skrypcie: bywa nim operator porównania wstawiony zamiast przypisania, przypisanie zamiast porównania albo przypisanie nowej wartości do stałej const.
Kilka odpowiedzi myli się regularnie. break przerywa całą pętlę, a continue tylko bieżący obrót, więc po continue pętla kręci się dalej i liczba obrotów zostaje ta sama. Brak break w switch daje przelot na kolejne przypadki, a nie skok do default. Pętla for...in oddaje indeks, nie wartość, więc wypisuje 0, 1, 2 zamiast nazw produktów. Liczbę parzystą wybiera reszta z dzielenia przez 2 równa zeru, czyli liczba % 2 === 0, nie iloraz.
W zadaniu praktycznym polecenie brzmi zwykle: „skrypt sprawdza, czy w polu wpisano liczbę z podanego zakresu, i wyświetla komunikat" albo „skrypt wypełnia listę danymi z tablicy". Pierwsze to jeden if z warunkiem złożonym oraz komunikat pokazany przez alert lub wstawiony do wskazanego elementu, drugie to pętla budująca napis z <li> i jedno przypisanie do innerHTML. Uruchomieniem takiego kodu z przycisku zajmuje się lekcja o zdarzeniach i formularzach, a dołączeniem pliku .js do strony lekcja o pierwszym skrypcie. Ściąga
if (warunek) { }
wykonaj blok, gdy warunek jest prawdziwy
else if (warunek) { }
kolejne pytanie, sprawdzane po nieudanym poprzednim
else { }
droga na wypadek, gdy żaden warunek nie był prawdziwy
if (a > 100 && a <= 200) { }
warunek złożony, przedział zamknięty z dwóch stron
switch (x) { case 1: }
wybór jednego przypadku z listy, porównanie jak ===
default:
przypadek dla wartości spoza listy, nieobowiązkowy
for (let i = 0; i < 5; i++)
5 obrotów, licznik przyjmuje wartości od 0 do 4
while (i < 5) { }
warunek przed obrotem, może nie wykonać się ani razu
do { } while (i < 5);
warunek po obrocie, wykona się co najmniej raz
for (const w of tab)
po wartościach tablicy, bez licznika
for (const k in tab)
po indeksach tablicy i kluczach obiektu
break;
wyjście z całej pętli albo koniec przypadku w switch
continue;
pominięcie reszty obrotu, przejście do następnego
el.innerHTML = tekst;
wstawienie napisu do elementu jako kodu HTML
Pobierz ściągę PDF