INF.03 · JavaScript
Słowniczek — JavaScript
Od pojęcia do działającej aplikacji
- Kod → próba → wniosek
- DOM i zdarzenia
- Własny projekt
Po tej lekcji: Powiążesz składnię z miejscem użycia i złożysz projekt oparty na danych.
Jak korzystać ze ściągi?
Nie ucz się listy poleceń w oderwaniu od działania. Znajdź pojęcie, wskaż przykład, przewidź wynik i dopiero uruchom. W projekcie kart dane są tablicą obiektów, pętla tworzy elementy, filtr wybiera widoczne rekordy, a zdarzenie input odświeża widok.
Dane JSON to nie program
JSON zapisuje dane: obiekty, tablice, napisy w podwójnych cudzysłowach, liczby, true/false/null. Nie zawiera funkcji, komentarzy ani końcowych przecinków. JSON.parse odczytuje tekst, JSON.stringify zamienia dane na tekst. Arkusz z czerwca 2026 zalecał skopiować strukturę z pliku JSON do skryptu; nie wymagał fetch. Własny przycisk fetch w projekcie jest dodatkowym rozwinięciem.
Ściąga pojęć z całego działu
| Nazwa | Opis / wyjaśnienie | Przykład składni |
|---|---|---|
| let | Deklaruje zmienną, której wartość może się zmieniać. | let cena = 10; |
| const | Blokuje ponowne przypisanie do nazwy; nie zamraża zawartości tablic i obiektów. | const PI = 3.14; |
| typeof | Zwraca typ wartości jako tekst. | typeof cena |
| === / == | Ścisłe porównanie bez konwersji / porównanie z możliwą konwersją typów. | 5 === "5" // false |
| if / else if / else | Instrukcja warunkowa. | if (x > 0) { ... } |
| for | Pętla licznikowa. | for (let i=0; i<10; i++) {} |
| while | Pętla warunkowa — powtarza się, dopóki warunek jest prawdziwy. | while (x < 10) {} |
| for...of | Pętla po elementach tablicy. | for (const x of tablica) {} |
| function | Klasyczna deklaracja funkcji. | function suma(a,b){ return a+b; } |
| Funkcja strzałkowa => | Funkcja bez własnego this; zwięzły callback, nie zamiennik każdej metody. | const suma = (a,b) => a+b; |
| addEventListener | Podpina obsługę zdarzenia (np. kliknięcia) pod element. | el.addEventListener("click", fn); |
| event.preventDefault() | Blokuje domyślne zachowanie zdarzenia (np. wysłanie formularza). | event.preventDefault(); |
| document.getElementById | Wybiera JEDEN element po atrybucie id. | document.getElementById("x"); |
| querySelector / querySelectorAll | Wybiera pierwszy / wszystkie elementy pasujące do selektora CSS. | document.querySelector(".karta"); |
| textContent | Odczyt/zmiana zwykłego tekstu elementu. | el.textContent = "Nowy tekst"; |
| innerHTML | Interpretuje HTML. Nie wstawiaj danych użytkownika; do tekstu użyj textContent. | el.innerHTML = "<b>Tekst</b>"; |
| style | Bezpośrednia zmiana pojedynczej właściwości CSS elementu. | el.style.color = "red"; |
| classList.add/remove/toggle | Dodaje / usuwa / przełącza klasę CSS elementu. | el.classList.toggle("aktywny"); |
| createElement | Tworzy nowy element (jeszcze niewidoczny na stronie). | document.createElement("li"); |
| appendChild | Wstawia utworzony element na koniec rodzica. | rodzic.appendChild(dziecko); |
| remove() | Usuwa element ze strony. | el.remove(); |
| localStorage.setItem/getItem | Magazyn napisów danego origin. Może być niedostępny lub wyczyszczony; bez haseł i tokenów sesji. | localStorage.setItem("k","v"); |
| setTimeout | Planuje jedno wywołanie najwcześniej po opóźnieniu w ms; może wykonać się później. | setTimeout(fn, 3000); |
| setInterval | Planuje powtarzane wywołania; czas niegwarantowany. Zatrzymaj clearInterval(id). | setInterval(fn, 1000); |
| Math.random() | Liczba od 0 włącznie do 1 wyłącznie; nie do tokenów bezpieczeństwa. | Math.random(); |
| Math.floor() | Zaokrągla liczbę w dół do pełnej liczby całkowitej. | Math.floor(3.7); // 3 |
| array.push() | Dodaje nowy element na koniec tablicy. | tablica.push("nowy"); |
| console.log() | Wypisuje wartość do konsoli przeglądarki (do debugowania). | console.log(zmienna); |
| Number / Number.isFinite | Konwersja napisu / sprawdzenie skończonej liczby. | Number("7"); // 7 |
| JSON.parse / stringify | Odczyt tekstu JSON / zapis danych do tekstu. | JSON.stringify([1,2]); |
| return | Oddaje wynik i kończy funkcję. | return suma; |
| fetch / response.ok | Pobranie zasobu / kontrola statusu HTTP. | if (!response.ok) throw new Error("HTTP"); |
Rozszerzenie: asynchroniczny odczyt
fetch zwraca Promise. await w funkcji async czeka na odpowiedź, lecz błąd HTTP404 sam nie odrzuca Promise — sprawdź response.ok. response.json odczytuje dane; potem sprawdź ich strukturę przed rysowaniem. try/catch pokazuje błąd, finally odblokowuje przycisk. file:// bywa blokowane; uruchom lokalny HTTP jak w START.txt. Nie wkładaj poufnych kluczy do JS: kod klienta jest dostępny dla odwiedzającego.
Najpierw krótki przykład, potem cały projekt
Każdy krótki przykład uruchamiaj osobno: w oddzielnym pliku skrypt.js lub na nowej pustej stronie. Nie doklejaj kilku przykładów z tym samym const do jednego pliku, bo ponowna deklaracja tej samej nazwy jest błędem. Przykłady konsolowe pokażą wynik w F12 → Console. Przy przykładach DOM najpierw utwórz wskazane elementy HTML i podłącz skrypt z defer. Fragment wymagający gotowego projektu jest tak oznaczony — wykonuj go w jego kontekście, nie jako pustą stronę.
JSON: tekst danych i obiekt w programie
JSON jest formatem tekstowym. Obiekt JavaScript i tekst JSON nie są tym samym, chociaż wyglądają podobnie.
Podstawowa forma: JSON.parse(tekst) odczytuje, JSON.stringify(dane) zapisuje
const tekst = '{"tytul":"Ocean","rok":2024}';
const film = JSON.parse(tekst);
console.log(film.tytul);
const zapis = JSON.stringify([film.tytul, film.rok]);
console.log(zapis);
Ocean ["Ocean",2024]
- JSON.parse przyjmuje napis. Z niego powstaje obiekt, którego właściwość odczytujesz film.tytul.
- W JSON klucze i napisy muszą mieć podwójne cudzysłowy. Nie ma komentarzy, funkcji ani końcowego przecinka. Błędny tekst wywoła wyjątek.
- JSON.stringify zamienia tablicę danych w tekst gotowy np. do pliku. Nie zmienia automatycznie istniejącego pliku na dysku.
fetch, async, await i try/catch — po jednym kroku
Ten fragment uruchamiaj z folderu karty przez lokalny serwer HTTP zgodnie z START.txt. Odczyt jest asynchroniczny: funkcja może poczekać, nie blokując całej strony.
Podstawowa forma: const odpowiedz = await fetch(adres); const dane = await odpowiedz.json(); wewnątrz funkcji async
async function wczytajDane() {
try {
const odpowiedz = await fetch('./dane.json');
if (!odpowiedz.ok) {
throw new Error(`HTTP ${odpowiedz.status}`);
}
const dane = await odpowiedz.json();
console.log(Array.isArray(dane));
} catch (blad) {
console.log('Nie udało się wczytać danych');
}
}
// W folderze projektu wywołaj w konsoli: wczytajDane();
- async oznacza funkcję zwracającą Promise — obietnicę późniejszego wyniku. await czeka na spełnienie danej obietnicy w tej funkcji.
- fetch dostaje adres względem strony. Pierwszy await oddaje odpowiedź HTTP, nie gotową tablicę; jej ok to informacja o statusie 200–299.
- HTTP404 nie musi odrzucić fetch, dlatego sprawdzamy ok. throw new Error tworzy i zgłasza błąd; catch odbiera go jako blad.
- json() odczytuje treść i parsuje JSON, to też etap asynchroniczny. W gotowym projekcie sprawdzamy następnie strukturę; sam poprawny JSON nie gwarantuje oczekiwanych pól. finally wykonuje końcowe sprzątanie po sukcesie lub błędzie.
Filtrowanie i pomijanie pustych wpisów w kartach
W projekcie szukamy tytułu bez rozróżniania wielkości liter. Najpierw przelicz dane na małym przykładzie, potem połącz z input.
Podstawowa forma: tablica.filter(element => warunek) daje nową tablicę; tekst.includes(fragment) sprawdza zawieranie
const wydarzenia = [{ tytul: 'Kodowanie' }, { tytul: 'Film' }];
const szukane = 'KOD'.toLocaleLowerCase('pl');
const widoczne = wydarzenia.filter(w =>
w.tytul.toLocaleLowerCase('pl').includes(szukane)
);
console.log(widoczne.length);
console.log(widoczne[0].tytul);
1 Kodowanie
- toLocaleLowerCase("pl") daje wersję tekstu małymi literami. To nowy napis, nie zmiana oryginalnego tytułu.
- filter wywołuje funkcję dla każdego wydarzenia i zachowuje te, dla których wynik jest prawdziwy. w jest aktualnym obiektem.
- includes sprawdza, czy napis zawiera fragment kod. Kodowanie pasuje, Film nie; wynik ma jeden element.
- W pełnym projekcie osobna pętla tworzy li tylko dla punktu, którego trim nie jest pusty. append(tytul,data,lista) dołącza kilka elementów, a replaceChildren przed rysowaniem zapobiega dublowaniu kart.
Jak czytać pozostałe zapisy w pełnym przykładzie
| Zapis | Znaczenie | Przykład użycia |
|---|---|---|
... i [...lista] | Spread rozkłada elementy iterowalne. W kalkulatorze [...NodeList] tworzy zwykłą tablicę, aby użyć reduce. | [...document.querySelectorAll(":checked")] |
reduce(callback, poczatek) | Po kolei oblicza nową wartość akumulatora; podany początek0 obsługuje także pustą listę. | [1,2].reduce((suma,x) => suma+x, 0) |
filter(callback) | Tworzy nową tablicę elementów spełniających test. Nie usuwa elementów z tablicy źródłowej. | filmy.filter(film => film.rok >= 2024) |
some / every | some pyta, czy choć jeden element spełnia warunek, every czy wszystkie. Dla pustej tablicy some=false, every=true. | pola.every(znak => znak !== "") |
([a,b,c]) => ... | Parametr callbacku zostaje rozpakowany z jednej tablicy do trzech nazw. To nie trzy osobne argumenty przekazane przez some. | linie.some(([a,b,c]) => pola[a] === pola[b]) |
warunek ? A : B | Wyrażenie warunkowe zwraca A przy prawdzie, B przy fałszu. Można go użyć po prawej stronie przypisania. | gracz = gracz === "O" ? "X" : "O"; |
Array(9).fill("") | Tworzy dziewięć pozycji i wypełnia je pustym napisem. fill z obiektem współdzieliłoby ten sam obiekt; tutaj używamy napisów. | let pola = Array(9).fill(""); |
replaceChildren / append | Pierwsza metoda zastępuje wszystkie dzieci elementu, druga dopisuje podane węzły/teksty na końcu. | karta.append(tytul, data, lista); |
Array.isArray / Number.isInteger | Kontrolują kształt tablicy i pełną liczbę; nie wykonują konwersji wejścia. | Number.isInteger(Number(pole.value)) |
Object / klucz dynamiczny | Obiekt przechowuje nazwane wartości; ceny[kod] używa aktualnego napisu w zmiennej kod jako nazwy właściwości. | ceny["html"] |
Math.floor / Intl.NumberFormat | floor zaokrągla w dół; NumberFormat tworzy obiekt formatujący do tekstu. Obliczenia finansowe projektu są w groszach. | Math.floor(1000 / 3) |
addEventListener / preventDefault | Pierwsza metoda rejestruje funkcję na zdarzenie, druga zatrzymuje jego domyślną akcję (np.wysłanieformularza), nie usuwa innych listenerów. | form.addEventListener("submit", e => e.preventDefault()); |
new Error / throw / catch / finally | new Error tworzy opis błędu, throw go zgłasza, catch przechwytuje, finally wykonuje końcowy etap po sukcesie lub błędzie. | throw new Error("Niepoprawne dane"); |
async / await / Promise | async funkcja zwraca obietnicę, await czeka na jej wynik w funkcji. Nie znaczy to, że wszystkie dalsze skrypty strony stoją. | const dane = await odpowiedz.json(); |
&& / || / ?? | && wymaga prawdy po obu stronach, || wybiera także dla pustego napisu/0, ?? tylko dla null/undefined. Te operatory mogą zwracać operandy, nie wyłącznie bool. | znak || "puste" |
=== i !== | Porównanie bez konwersji typów. Przypisanie ma pojedyncze =. | 7 === "7" // false |
Sprawdź w działaniu
Sprawdź mechanizm na działającym przykładzie
Zmień dane, przewidź wynik i wykonaj próbę. To działający JavaScript tego modelu, nie interpreter dowolnego wklejonego kodu.
Prześledź kod, potem zmień jedną rzecz
const wydarzenia = [{ tytul: "Dzień kodowania", punkty: ["HTML", "JS", ""] }];
for (const wydarzenie of wydarzenia) {
console.log(wydarzenie.tytul);
for (const punkt of wydarzenie.punkty) {
if (punkt.trim() === "") continue;
console.log(punkt);
}
}
Odtwórz przykład u siebie
Zapisz pokazany JavaScript w skrypt.js, a HTML w body zwykłego dokumentu z <!doctype html>, lang="pl", meta charset="UTF-8" i tytułem. W head podłącz <script src="skrypt.js" defer></script>. Przykłady z samym console.log możesz wykonać też w konsoli własnej pustej strony. Nie wklejaj nieznanych skryptów do konsoli zalogowanych serwisów. F12 → Console: sprawdź błędy; Sources: ustaw breakpoint, obejrzyj zmienne i przejdź krokowo.
Projekt: karty z danych i filtrowanie
INF.03-06-26.06-SG sprawdzał generowanie bloków z danych, obsługę zmiennej liczby rekordów i pomijanie pustych wpisów. Nasz autorski przykład używa wydarzeń szkolnych.
1. Każdy obiekt ma tytul, data i tablicę punkty. Nie zakładaj stałej liczby wydarzeń. Pętla tworzy article, h2, p i ol dla każdego rekordu. Pusty punkt po trim jest pomijany.
2. Filtr input porównuje tytuły po sprowadzeniu do małych liter. Przed ponownym rysowaniem replaceChildren usuwa stary widok, żeby nie dublować kart. Tekst trafia przez textContent.
3. Dopiero dodatkowy przycisk pobiera dane.json. await czeka na odpowiedź; sprawdź ok, odczytaj json i zweryfikuj strukturę. Przy błędzie zachowaj stare dane i pokaż informację.
4. Próby: dwa i trzy wydarzenia, pusta tablica, same puste punkty, brak dopasowania, HTTP404 i błędny JSON. Fetch wymaga HTTP — instrukcja w paczce. W Network obejrzyj status pliku.
Sprawdź w działaniu
Uruchom gotowy projekt i porównaj z kodem
W podglądzie działa gotowy kod. Komplet HTML/CSS/JS pobierzesz w paczce na końcu. Podgląd jest izolowany od konta BitEdu.
Pełny projekt: index.html
<!doctype html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>
Tablica wydarzeń / JSON i DOM
</title>
<link rel="stylesheet" href="styl.css">
<script src="skrypt.js" defer>
</script>
</head>
<body>
<main>
<h1>
Tablica wydarzeń / JSON i DOM
</h1>
<p>
Dane to tablica obiektów. Puste punkty programu pomijamy. To nasze dane szkolne, bez danych pacjentów.
</p>
<label for="filtr">
Szukaj wydarzenia
</label>
<input id="filtr" type="search">
<div id="karty" class="karty">
</div>
<p id="status" role="status">
</p>
<button id="pobierz" type="button">
Wczytaj plik JSON przez HTTP
</button>
<small>
Przycisk wymaga lokalnego serwera. Dane początkowe działają także po otwarciu pliku z dysku.
</small>
</main>
</body>
</html>
Pełny projekt: skrypt.js
let wydarzenia = [
{ tytul: 'Dzień kodowania', data: '2026-11-10', punkty: ['HTML', 'JavaScript', ''] },
{ tytul: 'Wieczór gier', data: '2026-11-12', punkty: ['Planszówki', '', ''] }
];
const kontener = document.querySelector('#karty');
const filtr = document.querySelector('#filtr');
const status = document.querySelector('#status');
function poprawneDane(dane) {
return Array.isArray(dane) && dane.length <= 100 && dane.every(w =>
w !== null && typeof w === 'object' && typeof w.tytul === 'string' &&
typeof w.data === 'string' && Array.isArray(w.punkty) &&
w.punkty.every(p => typeof p === 'string'));
}
function rysujKarty() {
kontener.replaceChildren();
const szukane = filtr.value.trim().toLocaleLowerCase('pl');
const widoczne = wydarzenia.filter(w => w.tytul.toLocaleLowerCase('pl').includes(szukane));
for (const wydarzenie of widoczne) {
const karta = document.createElement('article');
const tytul = document.createElement('h2');
tytul.textContent = wydarzenie.tytul;
const data = document.createElement('p');
data.textContent = `Termin: ${wydarzenie.data}`;
const lista = document.createElement('ol');
for (const punkt of wydarzenie.punkty) {
if (punkt.trim() === '') continue;
const element = document.createElement('li');
element.textContent = punkt;
lista.appendChild(element);
}
karta.append(tytul, data, lista);
kontener.appendChild(karta);
}
status.textContent = widoczne.length ? `Liczba wydarzeń: ${widoczne.length}.` : 'Brak pasujących wydarzeń.';
}
filtr.addEventListener('input', rysujKarty);
document.querySelector('#pobierz').addEventListener('click', async () => {
const przycisk = document.querySelector('#pobierz');
przycisk.disabled = true;
status.textContent = 'Wczytuję dane…';
try {
const odpowiedz = await fetch('./dane.json');
if (!odpowiedz.ok) throw new Error(`HTTP ${odpowiedz.status}`);
const dane = await odpowiedz.json();
if (!poprawneDane(dane)) throw new Error('Niepoprawna struktura danych');
wydarzenia = dane;
rysujKarty();
} catch (blad) {
status.textContent = 'Nie udało się wczytać danych. Uruchom lokalny serwer i sprawdź dane.json. Poprzednia lista pozostaje.';
console.warn(blad.message);
} finally {
przycisk.disabled = false;
}
});
rysujKarty();
Wygląd też jest częścią paczki
Folder projektu zawiera również pełny styl.css, a karty — dane.json. Rozpakuj ZIP JS / WARSZTAT ze „Źródeł i materiałów”. Otwórz index.html; dla dodatkowego odczytu JSON uruchom lokalny serwer opisany w START.txt. Podgląd nie zastępuje wykonania własnej wersji.
Ćwiczenie z pomocą · samodzielna praca
Twoja próba
Dodaj do danych trzecie wydarzenie z jednym niepustym punktem. Widok ma pokazać trzy karty i żadnych pustych punktów.
Zapisz: dane → przewidywany wynik → wynik próby → wyjaśnienie.
? Potrzebujesz pomocy? Rozwiązuj krok po kroku.
Krok 1 — pokaż podpowiedź
Zacznij od działającego przykładu i przewidź wynik bez uruchamiania.
Krok 2 — pokaż podpowiedź
Zmień jedną instrukcję lub jedną wartość. Obejrzyj Console i stan DOM.
Krok 3 — pokaż podpowiedź
Dodaj przypadek pusty albo graniczny. Jeśli wynik jest inny, ustaw breakpoint.
Otwórz tylko tyle podpowiedzi, ile potrzebujesz. Po każdym kroku wróć do zadania i sprawdź wynik.
Podsumowanie
Co warto zapamiętać
- Powiążesz składnię z miejscem użycia i złożysz projekt oparty na danych.
- Umiesz wskazać przyczynę wyniku w kodzie i sprawdzić przypadek graniczny.
- Quiz i dodatkowe zadania są w biurku; kod ocenia nauczyciel.
Dalej na swoim koncie
Rozgrzewki, quiz i zadania są w biurku ucznia.
Teoria jest otwarta dla wszystkich. Żeby rozwiązywać zadania, zapisywać szkice i widzieć swój postęp, zaloguj się.
Zaloguj się →Źródła i dalsza nauka
- JS / WARSZTAT.zip — 4 pełne projekty i START.txt
- CKE — informator INF.03 (wymagania INF.03.5)
- CKE — arkusz INF.03-02-24.06-SG, czat (kopia szkoły)
- CKE — arkusz INF.03-07-26.06-SG, plansza (kopia archiwalna)
- CKE — arkusz INF.03-06-26.06-SG, dane i DOM (kopia archiwalna)
- MDN — przewodnik JavaScript
- MDN — const
- MDN — fetch
- Dokumentacja składni omawianego języka