1/50
Wprowadzenie: HTML, CSS, JS - wzajemne relacje
Slajd przedstawia trójwarstwowy model nowoczesnych aplikacji internetowych oraz precyzyjny podział ról pomiędzy HTML, CSS i JavaScript.

Podział odpowiedzialności w architekturze WWW

  • HTML (struktura i semantyka): odpowiada za organizację treści dokumentu, hierarchię nagłówków oraz znaczenie logiczne elementów.
  • CSS (warstwa prezentacji): kontroluje wygląd wizualny, kolorystykę, typografię oraz adaptacyjne układy przestrzenne (Flexbox, Grid).
  • JavaScript (warstwa behawioralna): obsługuje interakcje z użytkownikiem, asynchroniczną komunikację sieciową i dynamiczne modyfikacje DOM.
  • Separacja odpowiedzialności: rozdzielenie treści od stylu i logiki ułatwia utrzymanie projektu, dostępność cyfrową i optymalizację SEO.
Trójwarstwowa architektura WWW: standard podziału technologii front-endowych na trzy odrębne, współpracujące warstwy: strukturę danych (HTML), stylizację graficzną (CSS) oraz logikę wykonawczą i interakcję (JavaScript). Zapewnia modularność, skalowalność i ułatwia testowanie kodu aplikacji.
<!DOCTYPE html>
<html lang="pl">
<head>
    <title>Synergia</title>
</head>
<body>
    <h1 id="tytul">Treść HTML</h1>
    <script src="app.js"></script>
</body>
</html>

Źródło: MDN Web Docs - HTML: HyperText Markup Language

2/50
Anatomia dokumentu HTML: HEAD vs BODY
Slajd omawia strukturę szkieletu dokumentu HTML5 ze szczególnym uwzględnieniem odrębnych zadań sekcji nagłówkowej i treści właściwej.

Dwie główne sekcje dokumentu hipertekstowego

  • Sekcja <head> (metadane): zawiera konfigurację kodowania UTF-8, tytuł strony, viewport dla urządzeń mobilnych oraz odnośniki do zasobów.
  • Sekcja <body> (treść renderowana): obejmuje wszystkie elementy widoczne w oknie przeglądarki, takie jak tekst, grafika, tabele i przyciski.
  • Deklaracja <!DOCTYPE html>: informuje parser przeglądarki o zastosowaniu nowoczesnego standardu HTML5 i zapobiega trybowi quirks mode.
  • Atrybut lang w znaczniku <html>: określa język naturalny dokumentu, wspierając czytniki ekranowe oraz algorytmy indeksujące wyszukiwarek.
Metadane dokumentu HTML: informacje techniczne opisujące właściwości strony internetowej umieszczane w sekcji <head>, które nie są bezpośrednio wyświetlane w oknie przeglądarki. Służą konfiguracji parsera, optymalizacji SEO oraz integracji z zewnętrznymi arkuszami stylów i skryptami.
<head>
    <meta name="description" content="Opis strony">
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <p>Widoczny tekst.</p>
</body>

Źródło: MDN Web Docs - HTML: HyperText Markup Language

3/50
Semantyczne tagowanie w HTML5
Slajd demonstruje zastosowanie znaczników semantycznych HTML5 w celu nadania strukturze strony jednoznacznego znaczenia maszynowego.

Dostępność cyfrowa i hierarchia logiczna dokumentu

  • Znaczniki strukturalne: zastąpienie generycznych kontenerów <div> elementami takimi jak <header>, <nav>, <main>, <article>, <aside> i <footer>.
  • Dostępność cyfrowa (a11y): semantyka umożliwia czytnikom ekranowym tworzenie drzewa ułatwień dostępu i sprawną nawigację użytkownikom z niepełnosprawnościami.
  • Pozycjonowanie w wyszukiwarkach (SEO): roboty indeksujące precyzyjniej oceniają wagę merytoryczną artykułów i powiązań między sekcjami.
  • Czytelność kodu źródłowego: ułatwia pracę zespołową i utrzymanie kodu dzięki intuicyjnym nazwom elementów architektonicznych.
Semantyczny HTML: metodologia tworzenia kodu HTML polegająca na stosowaniu znaczników odzwierciedlających znaczenie i rolę zawartych w nich informacji, a nie ich docelowy wygląd wizualny. Stanowi fundament dostępności cyfrowej zgodnie ze standardem WCAG oraz optymalizacji indeksowania wyszukiwarek.
<!-- Zamiast: <div class="naglowek"> -->
<header>...</header>
<main>
    <section>
        <article>...</article>
    </section>
</main>

Źródło: MDN Web Docs - HTML: HyperText Markup Language

4/50
Hiperłącza i osadzanie obrazów
Slajd omawia poprawne tworzenie linków hipertekstowych oraz osadzanie grafiki z uwzględnieniem dostępności i wydajności.

Fundamenty nawigacji i multimediów w sieci

  • Znacznik <a> (anchor): tworzy odsyłacz do innego adresu URL lub sekcji strony za pomocą wymaganego atrybutu href.
  • Bezpieczeństwo rel="noopener": przy otwieraniu łączy w nowej karcie (target="_blank") chroni przed atakami typu tabnabbing.
  • Atrybut alt w znaczniku <img>: dostarcza alternatywny opis tekstowy dla czytników ekranowych oraz w sytuacji braku pobrania pliku graficznego.
  • Wymiary width i height: definiowanie stałych wymiarów w pikselach zapobiega zjawisku przesunięć układu strony (Cumulative Layout Shift).
Hiperłącze (link): element odsyłający użytkownika lub parser do innego zasobu w sieci Web za pośrednictwem ujednoliconego identyfikatora URI/URL. Tworzy siatkę powiązań internetu, umożliwiając nieliniową nawigację pomiędzy dokumentami i usługami.
<a href="/strona" target="_blank">Nowa Karta</a>
<img src="zdjecie.jpg" alt="Opis dla SEO i niewidomych" width="300">

Źródło: MDN Web Docs - HTML: HyperText Markup Language

5/50
Organizacja treści: listy i tabele
Slajd przedstawia reguły porządkowania danych za pomocą list punktowanych, numerowanych oraz semantycznych tabel HTML.

Strukturalne prezentowanie informacji tabelarycznych i wyliczeń

  • Listy nieuporządkowane (<ul>): służą do grupowania elementów, których kolejność nie ma znaczenia merytorycznego.
  • Listy uporządkowane (<ol>): reprezentują sekwencje logiczne, procedury lub rankingi, w których kolejność punktów jest istotna.
  • Semantyka tabeli: wykorzystanie elementów <thead>, <tbody>, wierszy <tr> oraz komórek nagłówkowych <th> z atrybutem scope.
  • Dostępność danych tabelarycznych: znacznik <caption> dostarcza czytelny tytuł tabeli, a atrybuty nagłówków wspomagają syntezatory mowy.
Tabela semantyczna: struktura HTML służąca wyłącznie do prezentacji danych wielowymiarowych w układzie wierszy i kolumn, z wyraźnym rozróżnieniem nagłówków i treści. Zgodnie z dobrymi praktykami tabele nie mogą być używane do pozycjonowania układu strony (layoutu).
<ul>
    <li>Punkt 1</li>
    <li>Punkt 2</li>
</ul>
<table>
    <thead><tr><th>Klucz</th></tr></thead>
    <tbody><tr><td>Wartość</td></tr></tbody>
</table>

Źródło: MDN Web Docs - HTML: HyperText Markup Language

6/50
Formularze HTML (<form>): elementy wejściowe
Slajd omawia architekturę formularzy internetowych, rodzaje kontrolek formularza oraz powiązania etykiet z polami wejściowymi.

Interaktywne zbieranie danych od użytkownika

  • Atrybuty action i method: określają docelowy punkt końcowy API oraz metodę HTTP (GET do zapytań, POST do przesyłania danych).
  • Znacznik <input> i typy wejścia: definiuje kontrolki tekstowe, hasła, numeryczne, pola wyboru (checkbox, radio) oraz daty.
  • Etykiety <label> i atrybut for: powiązanie etykiety z identyfikatorem id pola powiększa obszar klikalny i wspiera technologie asystujące.
  • Elementy <textarea> i <select>: umożliwiają wprowadzanie wielowierszowego tekstu oraz wybór opcji z rozwijanej listy selektora.
Formularz HTML: sekcja dokumentu zawierająca interaktywne kontrolki umożliwiające użytkownikowi wprowadzanie, edycję i przesyłanie danych do serwera. Stanowi podstawowy mechanizm interakcji dwukierunkowej w aplikacjach internetowych.
<form method="POST" action="/login">
    <label for="u">Użytkownik:</label>
    <input type="text" id="u" name="user" required>
    <button type="submit">Wyślij</button>
</form>

Źródło: MDN Web Docs - HTML: HyperText Markup Language

7/50
Wbudowana walidacja formularzy (HTML5)
Slajd przedstawia deklaratywne mechanizmy weryfikacji poprawności danych wejściowych oferowane natywnie przez silnik przeglądarki.

Weryfikacja poprawności danych po stronie klienta bez kodu JS

  • Atrybut required: blokuje wysłanie formularza, dopóki użytkownik nie uzupełni wskazanego pola wejściowego.
  • Atrybut pattern z wyrażeniem regularnym: wymusza zgodność wprowadzonego łańcucha znaków z precyzyjnym wzorcem regex.
  • Ograniczenia min, max i maxlength: kontrolują dopuszczalny zakres wartości liczbowych lub maksymalną liczbę znaków w polu tekstowym.
  • Pseudoklasy CSS :valid i :invalid: umożliwiają natychmiastową stylizację wizualną poprawnych lub błędnych pól bez użycia JavaScriptu.
Walidacja klienta: wstępne sprawdzenie poprawności wprowadzonych danych w przeglądarce przed ich wysłaniem do serwera, zapewniające natychmiastową informację zwrotną. Nie zastępuje walidacji serwerowej, która jest bezwzględnie wymagana ze względów bezpieczeństwa.
<input type="text" 
    pattern="[A-Za-z]{3,}" 
    title="Wymagane co najmniej 3 litery"
    required>
    
<input type="number" min="18" max="99">

Źródło: MDN Web Docs - HTML: HyperText Markup Language

8/50
Osadzanie kodu JavaScript (<script>)
Slajd omawia techniki włączania kodu JavaScript do dokumentu HTML oraz wpływ atrybutów defer i async na wydajność ładowania strony.

Metody dołączania skryptów i kontrola renderowania strony

  • Kod wewnętrzny a pliki zewnętrzne: zalecane jest wydzielenie logiki do zewnętrznych plików .js z użyciem atrybutu src.
  • Atrybut defer: pobiera skrypt asynchronicznie w tle i wykonuje go gwarantowanie po zakończeniu parsowania drzewa DOM.
  • Atrybut async: pobiera skrypt asynchronicznie i wykonuje go natychmiast po pobraniu, przerywając parsowanie dokumentu.
  • Blokowanie renderowania (Parser-blocking): tradycyjne znaczniki <script> w sekcji <head> bez atrybutów zatrzymują budowę strony.
Atrybut defer: instrukcja dla przeglądarki nakazująca pobieranie zewnętrznego skryptu JavaScript w tle bez blokowania analizy składniowej HTML. Wykonanie skryptu następuje po kompletnym zbudowaniu drzewa DOM, tuż przed zdarzeniem DOMContentLoaded.
<!-- Zewnętrzny plik JS, nie blokuje renderowania -->
<script src="app.js" defer></script> 
<!-- Wewnętrzny kod JS -->
<script> console.log('Witaj'); </script>

Źródło: MDN Web Docs - HTML: HyperText Markup Language

9/50
Zmienne (let) i stałe (const) - zasięg blokowy
Slajd wyjaśnia zasady bezpiecznego deklarowania danych w JavaScript z wykorzystaniem słów kluczowych const i let oraz eliminację problemów var.

Nowoczesne deklaracje zmiennych w standardzie ECMAScript 6

  • Słowo kluczowe const: deklaruje stałe wiązanie referencji, którego nie można powtórnie przypisać nową wartością.
  • Słowo kluczowe let: umożliwia tworzenie zmiennych o zasięgu blokowym, których wartość może ulegać modyfikacjom w czasie wykonania.
  • Zasięg blokowy (Block scope): zmienne zadeklarowane w nawiasach klamrowych {} są niewidoczne poza tym blokiem kodu.
  • Temporal Dead Zone (TDZ): próba odwołania się do zmiennej let/const przed jej deklaracją wywołuje błąd ReferenceError, chroniąc przed błędami.
Temporal Dead Zone (TDZ): obszar w bloku kodu od momentu wejścia w zasięg bloku do linii, w której następuje formalna deklaracja zmiennej. Odwołanie się do identyfikatora znajdującego się w TDZ powoduje rzucenie wyjątku ReferenceError zamiast zwrócenia undefined.
const PI = 3.14; // Wartość niezmienna
let licznik = 0; // Wartość zmienna
licznik++;

if (true) {
    let x = 10;
    // console.log(x); // Dostępne
}
// console.log(x); // Błąd, poza zasięgiem blokowym

Źródło: MDN Web Docs - JavaScript Language Guide

10/50
Typy danych pierwotnych w JavaScript
Slajd omawia siedem pierwotnych typów danych w języku JavaScript oraz ich reprezentację w pamięci operacyjnej.

Wartości niemutowalne i model typowania dynamicznego

  • Wartości pierwotne (primitives): typ string, number, boolean, undefined, null, symbol oraz bigInt przekazywane są przez wartość.
  • Niemutowalność wartości pierwotnych: modyfikacja zmiennej pierwotnej tworzy nową wartość w pamięci bez zmiany oryginalnej wartości.
  • Różnica między undefined a null: undefined oznacza brak przypisania wartości przez programistę, a null to celowe wskazanie braku obiektu.
  • Operator typeof: zwraca łańcuch tekstowy z nazwą typu argumentu, z historyczną anomalią typeof null zwracającą 'object'.
Wartość pierwotna (Primitive): typ danych w języku JavaScript, który nie jest obiektem i nie posiada własnych mutowalnych właściwości ani metod. Wartości te są niezmienne w pamięci, a wszelkie operacje na nich zwracają zupełnie nowe instancje wartości.
let nazwa = "Ala";        // string
let wiek = 30;            // number
let jestAktywny = true;   // boolean
let bezWartosci;          // undefined

console.log(typeof nazwa); // "string"

Źródło: MDN Web Docs - JavaScript Language Guide

11/50
Operatory porównania (===) i logiczne
Slajd przedstawia działanie operatorów relacyjnych i logicznych oraz wykazuje konieczność stosowania operatora potrójnej równości.

Ścisła równość typów a pułapki niejawnej koercji

  • Ścisła równość (===): porównuje jednocześnie wartość oraz typ danych bez dokonywania niejawnych konwersji (strict equality).
  • Luźna równość (==): dokonuje niejawnej koercji typów według skomplikowanych reguł języka, co prowadzi do trudnych do wykrycia błędów.
  • Wartości falsy i truthy: wartości false, 0, "", null, undefined oraz NaN są konwertowane logicznie do false w warunkach.
  • Zwarcie logiczne (Short-circuiting): operatory && oraz || przerywają ewaluację po ustaleniu wyniku i zwracają ostatnią wartość.
Ścisła równość (Strict Equality): dwuargumentowy operator relacyjny w języku JavaScript oznaczany symbolem potrójnego znaku równości (===). Zwraca wartość logiczną true wyłącznie wtedy, gdy oba porównywane operandy mają identyczny typ danych oraz identyczną wartość.
10 == '10';  // true (luzne)
10 === '10'; // false (ścisłe, różne typy)

let a = 5;
if (a > 0 && a < 10) {
    console.log('Między 0 a 10');
}

Źródło: MDN Web Docs - JavaScript Language Guide

12/50
Instrukcje warunkowe (if/else i switch)
Slajd omawia konstrukcje rozgałęziające algorytm na podstawie ewaluacji wyrażeń logicznych oraz operator trójargumentowy.

Sterowanie przepływem wykonania programu

  • Konstrukcja if...else if...else: podstawowy mechanizm decyzyjny wykonujący blok kodu w zależności od prawdziwości warunku logicznego.
  • Instrukcja switch...case: czytelna alternatywa dla wielu warunków równościowych, wymagająca instrukcji break do zatrzymania opadania.
  • Klauzula default: wykonywana w instrukcji switch, gdy żadna ze sprawdzanych wartości case nie pasuje do testowanego wyrażenia.
  • Operator warunkowy (ternary): zwięzły zapis warunku jedno-wierszowego o składni: warunek ? wartość_gdy_prawda : wartość_gdy_fałsz.
Instrukcja switch: instrukcja sterująca przepływem programu w JavaScript dokonująca ścisłego porównania (===) wartości wyrażenia kontrolnego z kolejnymi etykietami case. Brak instrukcji break powoduje tzw. fall-through, czyli wykonanie kodu kolejnych bloków bez testowania warunku.
const status = 'nowy';
switch (status) {
    case 'nowy':
        console.log('Do zrobienia');
        break;
    default:
        console.log('Zrobione');
}

Źródło: MDN Web Docs - JavaScript Language Guide

13/50
Funkcje: deklaracja, wyrażenie i strzałkowe
Slajd porównuje trzy techniki tworzenia funkcji w JavaScript ze szczególnym uwzględnieniem leksykalnego wiązania this.

Definiowanie procedur i mechanizm wiązania kontekstu this

  • Deklaracja funkcji (Function declaration): podlega pełnemu hoistingowi, co umożliwia jej wywołanie w kodzie przed miejscem definicji.
  • Wyrażenie funkcyjne (Function expression): przypisuje anonimową lub nazwaną funkcję do zmiennej let/const, eliminując hoisting.
  • Funkcje strzałkowe (Arrow functions): wprowadzają zwięzłą składnię () => {} oraz leksykalne dziedziczenie kontekstu this z otoczenia.
  • Parametry domyślne: możliwość definiowania wartości domyślnych dla argumentów wywołania bezpośrednio w nagłówku funkcji.
Funkcja strzałkowa (Arrow Function): kompaktowa składnia definiowania funkcji wprowadzona w standardzie ECMAScript 2015 (ES6). Nie posiada własnego wiązania kontekstu this, obiektu arguments ani prototypu prototype, lecz przechwytuje kontekst this ze swojego zakresu leksykalnego.
// 1. Deklaracja
function suma(a, b) { return a + b; }

// 2. Strzałkowa (Arrow)
const roznica = (a, b) => a - b;

console.log(suma(1, 2));
console.log(roznica(5, 3));

Źródło: MDN Web Docs - JavaScript Language Guide

14/50
Pętle: for, while, for...of
Slajd omawia konstrukcje pętli w JavaScript ze szczególnym uwzględnieniem nowoczesnej pętli for...of do przeglądania kolekcji.

Iteracja po danych i strukturach iterowalnych

  • Klasyczna pętla for: trójczłonowa pętla z inicjalizacją licznika, warunkiem kontynuacji i krokiem inkrementacji.
  • Pętla while oraz do...while: wykonują blok instrukcji, dopóki warunek jest spełniony, z gwarancją co najmniej jednego przejścia w do...while.
  • Nowoczesna pętla for...of: przeznaczona do iterowania po obiektach implementujących protokół Iterable (tablice, łańcuchy, zbiory).
  • Instrukcje break i continue: pozwalają na natychmiastowe przerwanie wykonywania pętli lub pominięcie bieżącej iteracji.
Pętla for...of: nowoczesna konstrukcja iteracyjna standardu ES6 umożliwiająca bezpośrednie odczytywanie kolejnych wartości elementów dowolnego obiektu iterowalnego. Zapobiega typowym błędom indeksowania występującym w tradycyjnych pętlach licznikowych.
const imiona = ['Ola', 'Piotr', 'Kasia'];

// Klasyczna iteracja
for (let i = 0; i < imiona.length; i++) {
    console.log(imiona[i]);
}

// Nowoczesna iteracja
for (const imie of imiona) {
    console.log(imie);
}

Źródło: MDN Web Docs - JavaScript Language Guide

15/50
Tablice (Arrays): podstawowe metody
Slajd przedstawia dynamiczne tablice w JavaScript oraz metody modyfikujące ich długość i zawartość na obu końcach.

Zarządzanie uporządkowanymi kolekcjami danych

  • Indeksowanie od zera: elementy tablicy są adresowane liczbami całkowitymi, a właściwość length odzwierciedla liczbę elementów.
  • Metody push() oraz pop(): dodają lub usuwają elementy na końcu tablicy z wysoką wydajnością operacji stosowej O(1).
  • Metody unshift() oraz shift(): modyfikują początek tablicy, co wiąże się z koniecznością reindeksowania wszystkich pozostałych elementów.
  • Metody slice() oraz splice(): slice wycina fragment tablicy tworząc nową kopię, podczas gdy splice modyfikuje oryginalną tablicę w miejscu.
Tablica w JavaScript: specjalny typ obiektu wysokiego poziomu reprezentujący indeksowaną numerycznie listę elementów o zmiennej długości. Może przechowywać elementy o różnych typach danych i dynamicznie alokuje pamięć w miarę dodawania nowych wartości.
const lista = ['A', 'B'];
lista.push('C'); // ['A', 'B', 'C']
lista.pop();     // ['A', 'B']

console.log(lista[0]); // A (indeksacja od 0)

Źródło: MDN Web Docs - JavaScript Language Guide

16/50
Obiekty (Objects): właściwości i metody
Slajd omawia tworzenie obiektów za pomocą literałów, dostęp do właściwości oraz definiowanie metod i użycie słowa kluczowego this.

Struktury asocjacyjne typu klucz-wartość

  • Literał obiektowy {}: najprostszy i najbardziej wydajny sposób deklarowania obiektów zawierających pary klucz: wartość.
  • Dostęp przez kropkę i nawiasy kwadratowe: zapis obj.klucz lub obj['klucz'] umożliwiający dynamiczne odpytywanie właściwości zmienną.
  • Metody obiektowe: funkcje powiązane z właściwościami obiektu, mające dostęp do jego pól za pośrednictwem słowa kluczowego this.
  • Metody statyczne Object.keys/values: zwracają tablice zawierające nazwy kluczy, wartości lub pary [klucz, wartość] danego obiektu.
Obiekt w JavaScript: podstawowa złożona struktura danych w języku JavaScript stanowiąca nieuporządkowaną kolekcję właściwości (kluczy będących łańcuchami znaków lub symbolami) powiązanych z wartościami. Obiekty są przekazywane przez referencję w pamięci.
const samochod = {
    marka: 'Ford',
    rok: 2020,
    uruchom: function() { 
        console.log('Wrrrum!'); 
    }
};

console.log(samochod.marka);
samochod['rok'] = 2021;
samochod.uruchom();

Źródło: MDN Web Docs - JavaScript Language Guide

17/50
Funkcyjne metody tablic: forEach, map, filter
Slajd demonstruje transformacje tablic z wykorzystaniem funkcji wyższego rzędu bez mutowania źródłowych zbiorów danych.

Deklaratywne przetwarzanie kolekcji w stylu funkcyjnym

  • Metoda forEach(): wykonuje przekazaną funkcję zwrotną dla każdego elementu tablicy bez zwracania nowego zbioru (efekt uboczny).
  • Metoda map(): zwraca nową tablicę o tej samej długości, zawierającą wyniki transformacji każdego elementu tablicy źródłowej.
  • Metoda filter(): zwraca nową tablicę zawierającą wyłącznie te elementy, dla których predykat logiczny zwrócił true.
  • Metoda reduce(): agreguje wszystkie elementy tablicy do pojedynczej wartości skalarnej lub złożonej za pomocą akumulatora.
Funkcyjna transformacja danych: wzorzec programowania deklaratywnego polegający na przetwarzaniu zbiorów danych za pomocą łańcucha czystych funkcji wyższego rzędu (map, filter, reduce). Eliminuje potrzebę stosowania jawnych pętli i zmiennych pomocniczych, gwarantując niemutowalność danych źródłowych.
const liczby = [1, 2, 3];

// Zwraca nową tablicę: [2, 4, 6]
const podwojone = liczby.map(x => x * 2);

// Zwraca tablicę tylko parzystych: [2]
const parzyste = liczby.filter(x => x % 2 === 0);

liczby.forEach(x => console.log(x)); // Wykonuje akcję

Źródło: MDN Web Docs - JavaScript Language Guide

18/50
Destrukturyzacja obiektów i tablic (ES6)
Slajd omawia składnię destrukturyzacji umożliwiającą błyskawiczne wyodrębnianie pól obiektów i elementów tablic.

Eleganckie rozpakowywanie wartości do niezależnych zmiennych

  • Destrukturyzacja tablicowa [a, b]: przypisuje elementy tablicy do zmiennych na podstawie ich kolejności pozycyjnej.
  • Destrukturyzacja obiektowa {imie, wiek}: wyciąga właściwości obiektu na podstawie dopasowania nazw kluczy.
  • Przypisywanie z nową nazwą {stara: nowa}: pozwala nadać wyodrębnianej właściwości inną nazwę zmiennej w bieżącym zasięgu.
  • Wartości domyślne w destrukturyzacji: zabezpieczają przed wartością undefined w przypadku braku danego pola w źródłowym obiekcie.
Destrukturyzacja (Destructuring assignment): składnia wyrażenia w języku JavaScript umożliwiająca bezpośrednie wyodrębnianie danych z tablic lub właściwości z obiektów i przypisywanie ich do odrębnych zmiennych. Drastycznie upraszcza kod operujący na złożonych strukturach API.
const user = { imie: 'Anna', wiek: 25 };
const [a, b, c] = [10, 20, 30];

// Destrukturyzacja obiektu
const { imie, wiek } = user;
console.log(imie); // Anna

// Destrukturyzacja tablicy
console.log(b); // 20

Źródło: MDN Web Docs - JavaScript Language Guide

19/50
Operator spread (...) i parametry rest
Slajd przedstawia zastosowanie operatora trzech kropek do klonowania struktur, łączenia tablic oraz obsługi zmiennej liczby parametrów.

Elastyczne rozwijanie i agregowanie struktur danych

  • Operator rozwinięcia (Spread): rozbija elementy tablicy lub właściwości obiektu na pojedyncze elementy w miejscu wywołania.
  • Płytkie kopiowanie struktur: zapis [...tablica] lub {...obiekt} tworzy płytką kopię struktury bez modyfikowania oryginału.
  • Parametry resztkowe (Rest parameters): w nagłówku funkcji agregują nieokreśloną liczbę przekazanych argumentów do prawdziwej tablicy.
  • Zastąpienie archaicznego arguments: parametry rest oferują pełen dostęp do metod tablicowych (map, filter), w przeciwieństwie do obiektu arguments.
Operator Spread/Rest: wielozadaniowy operator oznaczany trzema kropkami (...) wprowadzony w standardzie ES6. Jako spread rozwija elementy kolekcji w miejscu oczekującym wielu wartości, a jako parametr rest gromadzi nadmiarowe argumenty funkcji w nowej tablicy.
const tab1 = [1, 2];
const tab2 = [...tab1, 3, 4]; // [1, 2, 3, 4]

const obj1 = { a: 1 };
const obj2 = { ...obj1, b: 2 }; // { a: 1, b: 2 }

// Rest (zbieranie argumentów w tablicę)
function logArgs(...args) { 
    console.log(args); 
}

Źródło: MDN Web Docs - JavaScript Language Guide

20/50
Template literals (backticks) i interpolacja
Slajd omawia literały szablonowe ograniczone grawisami (`), eliminujące uciążliwe konkatenacje łańcuchów tekstowych.

Wielowierszowe ciągi znaków i dynamiczne wstawianie wyrażeń

  • Składnia interpolacji ${wyrażenie}: umożliwia osadzanie wartości zmiennych oraz dowolnych wyrażeń JavaScript wewnątrz tekstu.
  • Natywne łańcuchy wielowierszowe: literały szablonowe zachowują znaki nowej linii bez konieczności stosowania sekwencji ucieczki \n.
  • Bezpieczeństwo i czytelność: zastępuje błędotwórcze łączenie tekstu za pomocą operatora plusa (+) na rzecz czytelnych szablonów.
  • Tagowane literały szablonowe: zaawansowany mechanizm przekazywania szablonu do funkcji przetwarzającej, stosowany w bibliotekach stylizacji.
Literał szablonowy (Template Literal): rodzaj literału łańcuchowego w standardzie ES6 ograniczonego znakami grawisu (`). Umożliwia wygodne osadzanie wyrażeń wewnątrz łańcucha za pomocą sekwencji ${} oraz naturalne tworzenie łańcuchów wielowierszowych bez znaków podziału linii.
const produkt = 'Laptop';
const cena = 3500;

// Interpolacja: Wstawienie zmiennych
const info = `Produkt: ${produkt} kosztuje ${cena} zł.`;

// Wieloliniowy ciąg:
const html = `
    <div class="karta">
        <h1>${produkt}</h1>
    </div>
`;

Źródło: MDN Web Docs - JavaScript Language Guide

21/50
Wprowadzenie do klas (class) i OOP w JS
Slajd wyjaśnia definicję klas, konstruktorów, dziedziczenia oraz pól prywatnych w nowoczesnym programowaniu obiektowym w JavaScript.

Obiektowość oparta na prototypach w nowoczesnej składni

  • Lukier składniowy (Syntactic sugar): klasy w JS stanowią czytelną nakładkę na istniejący od zawsze mechanizm dziedziczenia prototypowego.
  • Konstruktor i słowo super: metoda constructor() inicjalizuje instancję, a funkcja super() wywołuje konstruktor klasy nadrzędnej.
  • Prywatne pola klas (#pole): nowy standard ES2022 umożliwia hermetyzację pól za pomocą prefiksu #, uniemożliwiając dostęp z zewnątrz.
  • Metody statyczne (static): funkcje wywoływane bezpośrednio na poziomie samej klasy, bez potrzeby tworzenia jej egzemplarza.
Klasa w JavaScript: deklaracja wprowadzona w standardzie ECMAScript 2015 stanowiąca przejrzysty szablon do tworzenia obiektów z własnymi stanami i zachowaniami. Pod spodem opiera się w całości na łańcuchu prototypów języka JavaScript.
class Samochod {
    constructor(marka) {
        this.marka = marka;
    }
    opis() {
        return `To jest ${this.marka}.`;
    }
}

const mojSamochod = new Samochod('Audi');
console.log(mojSamochod.opis());

Źródło: MDN Web Docs - JavaScript Language Guide

22/50
Moduły JS (ES Modules: import/export)
Slajd omawia architekturę modułowości kodu JavaScript z wykorzystaniem natywnego mechanizmu ES Modules.

Standaryzacja modularnego podziału kodu w przeglądarce i Node.js

  • Eksport nazwany (named export): pozwala na wyeksportowanie wielu funkcji lub stałych pod ich jawnymi nazwami z jednego pliku.
  • Eksport domyślny (export default): definiuje jeden główny element modułu, który można zaimportować pod dowolną nazwą.
  • Atrybut type="module" w HTML: wymagany w znaczniku <script> w celu aktywowania natywnej obsługi instrukcji import w przeglądarce.
  • Izolacja zasięgu modułu: zmienne zadeklarowane wewnątrz modułu nie zanieczyszczają przestrzeni globalnej obiektu window.
ES Modules (ESM): oficjalny, standaryzowany system modułowy dla języka JavaScript wprowadzony w standardzie ES6. Zapewnia statyczną analizę zależności na etapie kompilacji, asynchroniczne ładowanie oraz ścisłą izolację przestrzeni nazw każdego pliku.
// plik utils.js
export const PI = 3.14; 
export function log(msg) { ... }

// plik app.js
import { PI, log } from './utils.js';
console.log(PI);
log('Z modułu');

Źródło: MDN Web Docs - JavaScript Language Guide

23/50
DOM: Document Object Model - wprowadzenie
Slajd przedstawia strukturę modelu obiektowego dokumentu oraz rolę globalnego obiektu document jako punktu wejścia do manipulacji stroną.

Drzewiasta reprezentacja dokumentu HTML w pamięci przeglądarki

  • Hierarchia węzłów (Nodes): drzewo DOM składa się z węzłów elementów, węzłów tekstowych oraz węzłów komentarzy.
  • Obiekt document: globalna instancja reprezentująca załadowaną stronę WWW, udostępniająca metody przeszukiwania i modyfikacji.
  • Konwersja HTML na drzewo DOM: parser przeglądarki przekształca znaczniki hipertekstowe na żywe obiekty JavaScript w pamięci RAM.
  • Synchronizacja ze stanem widoku: każda zmiana w drzewie DOM natychmiast inicjuje proces ponownego przeliczenia stylów i renderowania.
Document Object Model (DOM): niezależny od platformy i języka interfejs programistyczny (API) reprezentujący dokumenty HTML i XML jako zhierarchizowane drzewo połączonych obiektów. Umożliwia dynamiczny odczyt, modyfikację struktury, stylów i zawartości strony za pomocą kodu JavaScript.
console.log(document); // Zwraca cały obiekt dokumentu
console.log(document.body); // Dostęp do węzła body

Źródło: MDN Web Docs - JavaScript Language Guide

24/50
Wyszukiwanie elementów: getElementById()
Slajd omawia klasyczną metodę pobierania unikalnego węzła dokumentu na podstawie atrybutu id wraz z weryfikacją jej wyniku.

Najszybszy dostęp do elementu przez unikalny identyfikator

  • Bezpośredni wskaźnik: metoda przeszukuje wewnętrzne tablice skrótów silnika przeglądarki, oferując natychmiastowy czas dostępu O(1).
  • Unikalność identyfikatorów: zgodnie ze specyfikacją W3C identyfikator id musi być unikalny w obrębie całego dokumentu HTML.
  • Zwracana wartość null: w przypadku braku elementu o danym id metoda zwraca null, co wymaga sprawdzenia przed manipulacją właściwościami.
  • Wielkość liter w identyfikatorze: poszukiwanie identyfikatora jest ściśle wrażliwe na wielkość znaków (case-sensitive).
Metoda getElementById(): wbudowana metoda obiektu Document zwracająca referencję do obiektu Element reprezentującego element DOM o podanym identyfikatorze id. Jest najbardziej wydajną metodą lokalizacji pojedynczego węzła na stronie.
const mojDiv = document.getElementById('glowny-kontener');
if (mojDiv) {
    mojDiv.style.backgroundColor = 'yellow';
}

Źródło: MDN Web Docs - JavaScript Language Guide

25/50
Wyszukiwanie elementów: querySelector i querySelectorAll
Slajd przedstawia nowoczesne metody odnajdywania elementów w drzewie DOM za pomocą dowolnych selektorów CSS.

Uniwersalne selektory CSS w silniku JavaScript

  • Metoda querySelector(): zwraca pierwszy napotkany element pasujący do selektora CSS lub wartość null w razie braku trafienia.
  • Metoda querySelectorAll(): zwraca statyczną kolekcję NodeList zawierającą wszystkie elementy spełniające podane kryteria selektora.
  • Wsparcie dla złożonych selektorów: obsługuje klasy (.karta), identyfikatory (#id), atrybuty ([type="text"]) oraz relacje potomne (div > p).
  • Iteracja po NodeList: zwracana kolekcja NodeList posiada natywną metodę forEach(), co ułatwia jej bezpośrednie przetwarzanie.
Metoda querySelector: nowoczesna metoda przeszukiwania drzewa DOM przyjmująca jako argument ciąg znaków reprezentujący selektor CSS poziomu 3. Zwraca pierwszego pasującego potomka, umożliwiając elastyczne wyszukiwanie elementów bez stosowania archaicznych metod wyspecjalizowanych.
// Pierwszy element z klasa 'karta'
const pierwsza = document.querySelector('.karta'); 

// Wszystkie linki wewnątrz menu
const linki = document.querySelectorAll('nav a'); 

// Linki można iterować za pomocą forEach
linki.forEach(a => a.textContent += ' [OK]');

Źródło: MDN Web Docs - JavaScript Language Guide

26/50
Wyszukiwanie elementów: getElementsByClassName i TagName
Slajd omawia tradycyjne metody wyszukiwania elementów oraz pułapki związane z dynamicznymi kolekcjami żywymi.

Kolekcje żywe (HTMLCollection) i ich specyfika

  • Kolekcja żywa (Live collection): HTMLCollection natychmiast i automatycznie odzwierciedla wszelkie zmiany wprowadzane w drzewie DOM.
  • Brak metod tablicowych: obiekt HTMLCollection nie posiada metody forEach, co wymaga konwersji przez Array.from() przed mapowaniem.
  • Metoda getElementsByClassName(): wyszukuje wszystkie elementy posiadające wskazaną klasę CSS w bieżącym poddrzewie.
  • Metoda getElementsByTagName(): zwraca elementy o podanej nazwie znacznika, np. wszystkie akapity 'p' lub odnośniki 'a'.
Kolekcja HTMLCollection: obiekt reprezentujący dynamiczną, żywą listę elementów DOM uporządkowaną według kolejności występowania w dokumencie. Każda zmiana w drzewie DOM (usunięcie lub dodanie węzła) jest natychmiast odzwierciedlana w stanie tej kolekcji bez konieczności ponownego wywoływania metody wyszukiwania.
const paragrafy = document.getElementsByTagName('p');
const aktywne = document.getElementsByClassName('active');

// Uwaga: HTMLCollection nie ma metody .forEach!
// Należy użyć: Array.from(paragrafy).forEach(...)

Źródło: MDN Web Docs - JavaScript Language Guide

27/50
Modyfikacja treści: innerHTML vs textContent
Slajd analizuje różnice pomiędzy właściwościami innerHTML i textContent ze szczególnym uwzględnieniem obrony przed wstrzykiwaniem skryptów.

Bezpieczeństwo danych a podatności na ataki XSS

  • Właściwość textContent: bezpiecznie wstawia tekst jako zwykły ciąg znaków, automatycznie enkodując encje HTML (<, >, &).
  • Właściwość innerHTML: parsuje przekazany łańcuch jako kod znaczników HTML, co stwarza krytyczną podatność na ataki typu XSS.
  • Wydajność operacji: textContent modyfikuje wyłącznie węzły tekstowe, podczas gdy innerHTML zmusza silnik do pełnego parsowania drzewa.
  • Zasada obrony w głąb: dane pochodzące od użytkownika lub z zewnętrznego API należy bezwzględnie wstawiać za pomocą textContent.
Cross-Site Scripting (XSS): groźna luka bezpieczeństwa w aplikacjach internetowych polegająca na wstrzyknięciu i wykonaniu złośliwego kodu JavaScript w przeglądarce ofiary. Zastosowanie właściwości textContent zamiast innerHTML stanowi podstawową linię obrony przed tego typu atakami.
const div = document.getElementById('msg');

// Bezpieczne
div.textContent = "Witaj!"; 

// Renderuje tag (potencjalnie niebezpieczne)
div.innerHTML = "<b>Witaj!</b>"; 

// Pobranie zawartości
const html = div.innerHTML;

Źródło: MDN Web Docs - JavaScript Language Guide

28/50
Zarządzanie atrybutami (get, set, remove)
Slajd omawia metody odczytu, modyfikacji i usuwania atrybutów węzłów DOM oraz atrybuty danych dataset.

Manipulacja właściwościami znaczników HTML z poziomu skryptu

  • Metoda getAttribute(): odczytuje pierwotną wartość atrybutu zdefiniowaną w kodzie HTML znacznika.
  • Metoda setAttribute(): dynamicznie ustawia nową wartość wskazanego atrybutu lub tworzy go, jeśli jeszcze nie istnieje.
  • Metoda removeAttribute(): całkowicie usuwa atrybut z elementu (np. wyłączenie pola przez usunięcie atrybutu disabled).
  • Atrybuty danych (data-*): właściwość element.dataset udostępnia obiektowy dostęp do niestandardowych danych biznesowych osadzonych w znaczniku.
Atrybuty danych (Data attributes): mechanizm standardu HTML5 umożliwiający przechowywanie niestandardowych informacji w znacznikach za pomocą prefiksu data-*. W kodzie JavaScript wartości te są transparentnie odwzorowywane na właściwości obiektu dataset w formacie camelCase.
const img = document.querySelector('img');

img.setAttribute('src', 'nowy.jpg');
const aktualnySrc = img.getAttribute('src');

img.removeAttribute('width'); // Usuń atrybut width

Źródło: MDN Web Docs - JavaScript Language Guide

29/50
Zarządzanie klasami CSS (classList)
Slajd przedstawia interfejs classList jako wzorcowy sposób sterowania stylizacją i stanem komponentów interfejsu.

Manipulowanie stanem wizualnym komponentu za pomocą klas

  • Metoda add() i remove(): bezpiecznie dodają lub usuwają jedną bądź więcej klas CSS bez nadpisywania pozostałych stylów.
  • Metoda toggle(): przełącza obecność klasy: dodaje ją gdy jej brakuje, lub usuwa gdy jest obecna (idealna do menu i okien modalnych).
  • Metoda contains(): sprawdza czy element posiada daną klasę, zwracając wartość logiczną true lub false.
  • Eliminacja manipulacji className: zastępuje błędotwórcze operacje na łańcuchu className wymagające ręcznego parsowania spacji.
Interfejs classList: właściwość elementu DOM zwracająca stokenizowaną kolekcję DOMTokenList reprezentującą listę klas CSS danego węzła. Udostępnia wygodne i bezpieczne metody manipulacji klasami bez ryzyka przypadkowego usunięcia innych reguł stylistycznych.
const przycisk = document.getElementById('btn');

przycisk.classList.add('aktywny');
przycisk.classList.toggle('ukryty');

if (przycisk.classList.contains('aktywny')) {
    console.log('Przycisk jest aktywny.');
}

Źródło: MDN Web Docs - JavaScript Language Guide

30/50
Bezpośrednia modyfikacja stylu (inline style)
Slajd omawia reguły bezpośredniego modyfikowania stylów inline elementu z uwzględnieniem konwersji camelCase.

Dynamiczne ustawianie właściwości graficznych w obiekcie style

  • Obiekt element.style: umożliwia bezpośrednie nadawanie wartości właściwościom CSS o najwyższym priorytecie w kaskadzie.
  • Konwersja camelCase: wielowyrazowe nazwy CSS (np. background-color) są mapowane w JavaScript na styl wielbłądzi (backgroundColor).
  • Wymóg podawania jednostek: wartości wymiarowe muszą bezwzględnie zawierać jednostki tekstowe, np. '20px' zamiast samej liczby 20.
  • Zasada separacji stylów: zaleca się modyfikację stylów poprzez dodawanie klas CSS (classList), ograniczając inline do wartości dynamicznych.
Styl inline: deklaracja stylów CSS przypisana bezpośrednio do konkretnego elementu DOM za pośrednictwem atrybutu style lub właściwości JavaScript element.style. Posiada wysoki priorytet w specyficzności kaskady CSS, co może utrudniać globalne zarządzanie motywem graficznym.
const div = document.getElementById('msg');

// Zmiana koloru tła i marginesu
div.style.backgroundColor = 'navy';
div.style.marginTop = '10px';

// Usuń styl (wraca do stylów z CSS)
div.style.backgroundColor = '';

Źródło: MDN Web Docs - JavaScript Language Guide

31/50
Tworzenie i wstawianie nowych elementów
Slajd demonstruje pełen cykl życia dynamicznego węzła DOM: utworzenie, konfigurację atrybutów oraz bezpieczne wpięcie do drzewa dokumentu.

Dynamiczne generowanie struktury strony z createElement i append

  • Metoda document.createElement(): tworzy w pamięci operacyjnej nowy, odłączony od dokumentu węzeł wskazanego typu elementu.
  • Konfiguracja nowego węzła: przypisanie zawartości tekstowej (textContent), klas CSS (classList) oraz niezbędnych atrybutów.
  • Metoda append() i appendChild(): wstawiają gotowy element jako ostatnie dziecko wybranego kontenera nadrzędnego.
  • Użycie DocumentFragment: optymalizuje operacje wstawiania wielu elementów, minimalizując kosztowne przeliczania układu (reflow).
DocumentFragment: lekki, niewidoczny kontener w pamięci operacyjnej zdolny do przechowywania poddrzewa węzłów DOM. Wstawienie fragmentu do właściwego dokumentu powoduje przeniesienie wszystkich jego dzieci za pomocą pojedynczej operacji renderowania, co zapobiega zjawisku reflow.
const nowyP = document.createElement('p');
nowyP.textContent = 'Utworzono dynamicznie.';
nowyP.classList.add('info');

const kontener = document.getElementById('glowny');
// Wstaw na koniec kontenera
kontener.appendChild(nowyP);

// Usuwanie elementu
nowyP.remove();

Źródło: MDN Web Docs - JavaScript Language Guide

32/50
Model zdarzeń: nasłuchiwanie (addEventListener)
Slajd omawia wzorcowy mechanizm rejestrowania procedur obsługi zdarzeń za pomocą metody addEventListener.

Architektura sterowana zdarzeniami w przeglądarce

  • Rejestracja wielu słuchaczy: addEventListener pozwala przypisać wiele niezależnych funkcji obsługi do tego samego zdarzenia.
  • Separacja kodu od HTML: eliminuje przestarzałe atrybuty zdarzeń w kodzie znaczników (takie jak onclick="...") na rzecz czystego JS.
  • Metoda removeEventListener(): umożliwia usunięcie słuchacza i zapobiega wyciekom pamięci w aplikacjach typu SPA.
  • Trzeci parametr opcji: pozwala skonfigurować nasłuchiwanie w fazie przechwytywania (capture) lub jednorazowe wykonanie (once: true).
Architektura sterowana zdarzeniami: paradygmat programowania, w którym przepływ sterowania aplikacji jest determinowany przez wystąpienie zewnętrznych zdarzeń, takich jak akcje użytkownika (kliknięcia, ruch myszy), sygnały sprzętowe czy komunikaty sieciowe. W przeglądarce bazuje na rejestracji funkcji callback.
const btn = document.getElementById('clicker');

btn.addEventListener('click', function() {
    console.log('Kliknięto!');
});

// Usuwanie nasłuchu
btn.removeEventListener('click', mojaFunkcja);

Źródło: MDN Web Docs - JavaScript Language Guide

33/50
Obiekt Event: target, currentTarget, preventDefault
Slajd szczegółowo analizuje właściwości obiektu Event przekazywanego automatycznie do każdej funkcji obsługi zdarzenia.

Przetwarzanie metadanych zdarzenia i blokowanie akcji domyślnych

  • Właściwość event.target: wskazuje rzeczywisty, najgłębszy element potomny w drzewie DOM, na którym zainicjowano zdarzenie.
  • Właściwość event.currentTarget: wskazuje element, do którego aktualnie przypisany jest wykonywany nasłuchiwacz zdarzenia.
  • Metoda event.preventDefault(): blokuje wykonanie domyślnej akcji przeglądarki (np. przeładowanie strony przy wysyłaniu formularza).
  • Właściwości typu i czasu: obiekt dostarcza informacje o typie zdarzenia (type), znaczniku czasu (timeStamp) oraz koordynatach myszy.
Obiekt Event: obiekt tworzony automatycznie przez środowisko uruchomieniowe przeglądarki w chwili wystąpienia zdarzenia, przekazywany jako pierwszy argument do funkcji nasłuchującej. Zawiera kompletny zestaw metadanych oraz metody kontroli propagacji zdarzenia.
document.querySelector('a').addEventListener('click', (e) => {
    e.preventDefault();
    console.log('Przejście zablokowane!');
});

Źródło: MDN Web Docs - JavaScript Language Guide

34/50
Typy zdarzeń: obsługa myszy i wskaźnika
Slajd omawia obsługę kliknięć, najechania kursorem oraz różnice pomiędzy zdarzeniami mouseover a mouseenter.

Interakcje użytkownika realizowane za pomocą kursora

  • Zdarzenia click oraz dblclick: wyzwalane po naciśnięciu i zwolnieniu głównego przycisku myszy nad elementem.
  • Różnica mouseover vs mouseenter: mouseenter nie bąbelkuje do elementów nadrzędnych, co zapobiega migotaniu przy elementach potomnych.
  • Zdarzenie contextmenu: pozwala na przechwycenie kliknięcia prawym przyciskiem myszy i wdrożenie własnego menu kontekstowego.
  • Współrzędne wskaźnika: właściwości clientX/Y oraz pageX/Y precyzyjnie określają pozycję kursora względem okna lub dokumentu.
Zdarzenia wskaźnika (Pointer Events): nowoczesny standard obsługi interakcji wskazujących unifikujący obsługę myszy, ekranów dotykowych oraz rysików w ramach spójnego zestawu zdarzeń przeglądarkowych. Upraszcza tworzenie aplikacji wieloplatformowych.
const div = document.getElementById('box');
div.addEventListener('mouseover', () => {
    div.style.backgroundColor = 'red';
});
div.addEventListener('mouseout', () => {
    div.style.backgroundColor = 'initial';
});

Źródło: MDN Web Docs - JavaScript Language Guide

35/50
Typy zdarzeń: obsługa klawiatury
Slajd przedstawia zdarzenia keydown i keyup oraz standardowe właściwości e.key i e.code do identyfikacji klawiszy.

Przechwytywanie wprowadzania tekstu i skrótów klawiszowych

  • Zdarzenie keydown: generowane natychmiast w chwili wciśnięcia dowolnego klawisza fizycznego na klawiaturze.
  • Zdarzenie keyup: wyzwalane w momencie zwolnienia uprzednio wciśniętego klawisza przez użytkownika.
  • Właściwość event.key: zwraca reprezentację znakową klawisza uwzględniającą układ klawiatury i stan klawiszy modyfikujących (np. 'Enter', 'a', 'A').
  • Właściwość event.code: identyfikuje fizyczny kod klawisza na klawiaturze (np. 'KeyA', 'ArrowDown') niezależnie od języka systemu.
Klawisze modyfikujące: specjalne klawisze klawiatury (Ctrl, Alt, Shift, Meta), których stan podczas wystąpienia zdarzenia jest odczytywany za pośrednictwem właściwości logicznych ctrlKey, altKey, shiftKey i metaKey obiektu zdarzenia. Umożliwiają tworzenie zaawansowanych skrótów klawiszowych.
document.addEventListener('keydown', (e) => {
    if (e.key === 'Escape') {
        console.log('Wciśnięto ESC.');
    }
});

Źródło: MDN Web Docs - JavaScript Language Guide

36/50
Typy zdarzeń: formularze (submit, input, change)
Slajd omawia zdarzenia związane z interakcją formularzową ze szczególnym uwzględnieniem zdarzenia submit i walidacji w locie.

Reagowanie na edycję pól i asynchroniczne wysyłanie formularza

  • Zdarzenie submit: przechwytuje zamiar wysłania formularza, umożliwiając walidację JS i zablokowanie przeładowania przez preventDefault().
  • Zdarzenie input: wyzwalane natychmiast przy każdej pojedynczej zmianie wartości w polu tekstowym (idealne do wyszukiwania live).
  • Zdarzenie change: emitowane dopiero w chwili utraty fokusu przez pole, gdy jego zawartość uległa faktycznej zmianie.
  • Zdarzenia focus i blur: sygnalizują aktywację lub opuszczenie pola wejściowego, służąc do animacji etykiet i komunikatów pomocy.
Zdarzenie submit: kluczowe zdarzenie formularza emitowane na poziomie elementu <form> w chwili naciśnięcia przycisku typu submit lub klawisza Enter w polu tekstowym. Przechwycenie tego zdarzenia w JavaScript stanowi fundament asynchronicznej komunikacji typu AJAX/Fetch.
const input = document.querySelector('input');

input.addEventListener('input', (e) => {
    console.log(e.target.value); // Wartość pola w czasie rzeczywistym
});

document.querySelector('form').addEventListener('submit', (e) => {
    e.preventDefault();
    console.log('Formularz zweryfikowany.');
});

Źródło: MDN Web Docs - JavaScript Language Guide

37/50
Propagacja zdarzeń: bubbling i capturing
Slajd wyjaśnia trójfazowy model przepływu zdarzeń w przeglądarce oraz metody kontrolowania rozprzestrzeniania się sygnału.

Fazy podróży zdarzenia przez hierarchię drzewa DOM

  • Faza 1: Przechwytywanie (Capturing): zdarzenie wędruje w dół od obiektu window i document przez przodków aż do elementu docelowego.
  • Faza 2: Cel (Target phase): zdarzenie osiąga docelowy węzeł DOM, na którym nastąpiła bezpośrednia akcja użytkownika.
  • Faza 3: Bąbelkowanie (Bubbling): zdarzenie wraca w górę drzewa DOM od elementu docelowego do korzenia dokumentu.
  • Metoda stopPropagation(): zatrzymuje dalszą wędrówkę zdarzenia w bieżącej fazie, izolując zachowanie komponentu.
Bąbelkowanie zdarzeń (Event Bubbling): mechanizm propagacji zdarzeń w standardzie DOM Level 2, w którym zdarzenie po obsłużeniu na elemencie źródłowym wędruje w górę po drzewie genealogicznym dokumentu, wyzwalając przypisane procedury obsługi na wszystkich elementach nadrzędnych.
// Zatrzymanie propagacji (powstrzymuje bubbling)
const child = document.getElementById('child');
child.addEventListener('click', (e) => {
    console.log('Kliknięto dziecko');
    e.stopPropagation(); // Zdarzenie nie pójdzie do rodzica
});

Źródło: MDN Web Docs - JavaScript Language Guide

38/50
Delegacja zdarzeń: efektywność i dynamika
Slajd przedstawia wzorzec architektoniczny delegacji zdarzeń redukujący zużycie zasobów i obsługujący dynamiczne elementy.

Obsługa setek elementów za pomocą pojedynczego listenera na rodzicu

  • Jeden słuchacz na rodzicu: zamiast rejestrować osobne funkcje na setkach elementów <li>, rejestrujemy jeden nasłuchiwacz na liście <ul>.
  • Rozpoznawanie celu przez e.target: wykorzystanie bąbelkowania i weryfikacja znacznika potomka lub metody e.target.closest().
  • Oszczędność pamięci operacyjnej: drastyczne zmniejszenie liczby obiektów funkcji w pamięci RAM przeglądarki przy długich listach danych.
  • Automatyczna obsługa nowych węzłów: elementy dodane do listy dynamicznie w przyszłości są natychmiast obsługiwane bez dodawania listenerów.
Delegacja zdarzeń (Event Delegation): wzorzec projektowy w inżynierii front-endowej polegający na wykorzystaniu mechanizmu bąbelkowania zdarzeń do rejestracji pojedynczej procedury obsługi na elemencie nadrzędnym zamiast rejestrowania wielu procedur na elementach podrzędnych. Kluczowy dla wydajności dynamicznych interfejsów.
const lista = document.getElementById('lista');

lista.addEventListener('click', (e) => {
    if (e.target.tagName === 'LI') {
        console.log(`Kliknięto: ${e.target.textContent}`);
    }
});

Źródło: MDN Web Docs - JavaScript Language Guide

39/50
Asynchroniczność w JS: jednowątkowość i Event Loop
Slajd omawia model wykonawczy silnika JavaScript, jednowątkowy stos wywołań oraz mechanizm pętli zdarzeń.

Wielozadaniowość bez blokowania głównego wątku przeglądarki

  • Jednowątkowy stos wywołań (Call Stack): JavaScript wykonuje synchronicznie jedną operację w danym momencie w głównym wątku UI.
  • Web APIs w tle: operacje sieciowe, timery i zdarzenia są delegowane do wielowątkowego silnika przeglądarki poza środowiskiem JS.
  • Pętla zdarzeń (Event Loop): nieustannie monitoruje stos wywołań; gdy stos jest pusty, pobiera zadania oczekujące w kolejkach.
  • Zapobieganie zamrażaniu interfejsu: asynchroniczność pozwala na płynne renderowanie widoku i responsywność interfejsu podczas operacji I/O.
Pętla zdarzeń (Event Loop): mechanizm koordynujący działanie silnika JavaScript odpowiedzialny za ciągłe sprawdzanie, czy stos wywołań jest pusty, i przenoszenie gotowych funkcji zwrotnych z kolejek zadań (makro i mikrozadań) na stos w celu ich bezpiecznego wykonania.
// Przykładowa asynchroniczna funkcja
setTimeout(() => {
    console.log('Po 2 sekundach');
}, 2000); 

console.log('Wykonuje się natychmiast');

Źródło: MDN Web Docs - JavaScript Language Guide

40/50
Funkcje zwrotne (callbacks) i problem callback hell
Slajd analizuje mechanizm przekazywania funkcji zwrotnych oraz problemy z czytelnością i obsługą błędów w zagnieżdżonych strukturach.

Historyczny wzorzec asynchroniczności i jego ograniczenia

  • Definicja callbacku: funkcja przekazywana jako argument do innej funkcji, która zostanie wywołana po zakończeniu operacji asynchronicznej.
  • Problem piramidy zagłady (Callback Hell): wielopoziomowe zagnieżdżanie wywołań asynchronicznych tworzy nieczytelny kod w kształcie trójkąta.
  • Trudności z obsługą błędów: konieczność żmudnego sprawdzania parametru błędu (if (err)) w każdym kolejnym zagnieżdżeniu.
  • Ewolucja w stronę Promise: ograniczenia estetyczne i logiczne callbacków doprowadziły do powstania natywnego standardu Obietnic w ES6.
Piramida zagłady (Callback Hell): antywzorzec programistyczny w języku JavaScript powstający na skutek wielokrotnego, głębokiego zagnieżdżania asynchronicznych funkcji zwrotnych. Prowadzi do skrajnego spadku czytelności kodu, utrudnia debugowanie oraz uniemożliwia przejrzystą propagację błędów.
pobierzUzytkownika(id, (user) => {
    pobierzPosty(user.id, (posts) => {
        // ... więcej zagnieżdżenia
        wyswietl(posts);
    });
});

Źródło: MDN Web Docs - JavaScript Language Guide

41/50
Obietnice (Promises): stany i obsługa błędów
Slajd omawia architekturę obiektu Promise, jego trzy niezmienne stany oraz przejrzystą propagację sukcesu i wyjątków.

Nowoczesny paradygmat asynchroniczny z metodami then, catch i finally

  • Trzy stany Obietnicy: pending (w toku), fulfilled (spełniona z sukcesem) oraz rejected (odrzucona z błędem).
  • Niemutowalność stanu: po przejściu ze stanu pending do fulfilled lub rejected stan obietnicy staje się trwale zamrożony.
  • Metody .then() i .catch(): metoda .then rejestruje konsumenta danych sukcesu, a .catch centralizuje obsługę wszelkich błędów z łańcucha.
  • Metoda .finally(): wykonywana zawsze bez względu na ostateczny stan obietnicy, idealna do wyłączania wskaźników ładowania danych.
Obiekt Promise (Obietnica): wbudowany w język obiekt reprezentujący ewentualny wynik (wartość lub powód odrzucenia) asynchronicznej operacji, która może zakończyć się w przyszłości. Stanowi fundament nowoczesnego asynchronicznego programowania w JavaScript.
const promise = new Promise((resolve, reject) => {
    // resolve w przypadku sukcesu, reject w przypadku błędu
    if (true) resolve('Dane gotowe');
    else reject('Błąd');
});

promise.then(data => {
    console.log(data); // Sukces
}).catch(error => {
    console.error(error); // Błąd
});

Źródło: MDN Web Docs - JavaScript Language Guide

42/50
Łańcuchowanie obietnic (Promise chaining)
Slajd demonstruje technikę łączenia kolejnych wywołań .then w celu wyeliminowania zagnieżdżeń i płaskiej organizacji kodu.

Sekwencyjne wykonywanie asynchronicznych zadań zależnych

  • Płaska struktura kodu: zwrócenie nowej obietnicy z wnętrza metody .then() przekazuje jej rezultat do kolejnego ogniwa w łańcuchu.
  • Pojedynczy blok .catch(): jeden blok obsługi błędów na końcu łańcucha przechwytuje wyjątek rzucony przez dowolne poprzedzające ogniwo.
  • Metody współbieżne Promise.all(): wykonuje równolegle zestaw wielu niezależnych obietnic i czeka na zakończenie wszystkich operacji.
  • Metoda Promise.race() oraz allSettled(): race zwraca wynik pierwszej zakończonej obietnicy, a allSettled raportuje stany wszystkich zadań.
Łańcuchowanie obietnic (Promise Chaining): wzorzec programowania asynchronicznego polegający na sekwencyjnym łączeniu metod .then() obiektu Promise. Każde ogniwo przetwarza dane i zwraca kolejną obietnicę, tworząc czytelny, płaski przepływ danych odporny na zagnieżdżenia.
fetch('/users/1')
    .then(res => res.json()) // 1. Zwraca Promise
    .then(user => fetch(`/posts/${user.id}`)) // 2. Zwraca Promise
    .then(res => res.json())
    .then(posts => {
        console.log(posts); // Dane po wszystkich krokach
    });

Źródło: MDN Web Docs - JavaScript Language Guide

43/50
Fetch API: asynchroniczne pobieranie danych (GET)
Slajd omawia pobieranie zasobów przez protokół HTTP za pomocą funkcji fetch oraz kardynalną zasadę weryfikacji flagi response.ok.

Nowoczesny interfejs komunikacji sieciowej oparty na Obietnicach

  • Zastąpienie XMLHttpRequest: Fetch API dostarcza elegancki, natywny interfejs asynchroniczny zintegrowany z modelem Promise.
  • Pułapka błędów HTTP (404/500): funkcja fetch() nie odrzuca obietnicy przy kodach błędów serwera; reject występuje tylko przy awarii sieci.
  • Weryfikacja flagi response.ok: programista musi jawnym warunkiem if (!response.ok) sprawdzić status odpowiedzi (zakres 200-299).
  • Metoda response.json(): asynchronicznie parsuje strumień odpowiedzi serwera do postaci natywnego obiektu JavaScript.
Fetch API: nowoczesny standard sieciowy przeglądarek definiujący ujednolicony interfejs programistyczny do pobierania i wysyłania zasobów przez protokół HTTP/HTTPS. W przeciwieństwie do archaicznego XMLHttpRequest opiera się na obiektach Request, Response i Promise.
fetch('https://api.example.com/data')
    .then(res => {
        if (!res.ok) throw new Error('Status: ' + res.status);
        return res.json();
    })
    .then(data => {
        console.log(data);
    })
    .catch(err => {
        console.error(err);
    });

Źródło: MDN Web Docs - JavaScript Language Guide

44/50
Fetch API: wysyłanie danych metodą POST
Slajd przedstawia konfigurację obiektu opcji w Fetch API do wysyłania danych na serwer w formacie JSON.

Przesyłanie struktur JSON i konfiguracja nagłówków żądania

  • Definicja metody HTTP: jawne ustawienie właściwości method: 'POST' lub 'PUT' w obiekcie konfiguracyjnym.
  • Nagłówek Content-Type: informuje serwer o formacie przesyłanego ładunku za pomocą wpisu 'application/json'.
  • Serializacja obiektu w body: pole body wymaga przekazania tekstu sformatowanego funkcją JSON.stringify(dane).
  • Obsługa odpowiedzi zwrotnej: odczytanie potwierdzenia lub nowo utworzonego obiektu z identyfikatorem zwróconym przez endpoint API.
Metoda HTTP POST: jedna z podstawowych metod protokołu HTTP służąca do przesyłania danych zebranych w kliencie do serwera w celu ich utworzenia lub przetworzenia w bazie danych. W aplikacjach SPA dane są najczęściej kodowane w standardzie JSON.
const dane = { tytul: 'Nowy post' };

fetch('/posts', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(dane) // Konwersja obiektu na JSON
})
.then(res => res.json())
.then(nowyPost => console.log(nowyPost));

Źródło: MDN Web Docs - JavaScript Language Guide

45/50
Async/Await: synchroniczny zapis asynchroniczności
Slajd omawia słowa kluczowe async oraz await, które umożliwiają pisanie asynchronicznego kodu wyglądającego jak kod sekwencyjny.

Elegancki lukier składniowy dla Obietnic z obsługą try/catch

  • Słowo kluczowe async: oznacza funkcję asynchroniczną i gwarantuje, że zawsze zwróci ona obiekt typu Promise.
  • Słowo kluczowe await: zatrzymuje wykonanie bieżącej funkcji async do momentu rozstrzygnięcia obietnicy, bez blokowania wątku głównego.
  • Klasyczna obsługa błędów try...catch: umożliwia przechwytywanie wyjątków sieciowych i logicznych w standardowy sposób strukturalny.
  • Zwiększenie czytelności: eliminuje wielokrotne łańcuchy .then() na rzecz intuicyjnych linii kodu przypominających styl synchroniczny.
Składnia async/await: mechanizm językowy wprowadzony w standardzie ES2017 (ES8) stanowiący czytelną warstwę abstrakcji nad obiektami Promise. Umożliwia konstruowanie asynchronicznego przepływu sterowania z użyciem znanych struktur synchronicznych.
async function pobierzUsera(id) {
    try {
        const res = await fetch(`/users/${id}`);
        if (!res.ok) throw new Error('Błąd HTTP');
        const user = await res.json();
        return user;
    } catch (err) {
        console.error("Błąd fetch:", err);
    }
}

Źródło: MDN Web Docs - JavaScript Language Guide

46/50
Magazyn danych przeglądarki: localStorage
Slajd analizuje mechanizm Web Storage, różnice pomiędzy localStorage a sessionStorage oraz aspekty bezpieczeństwa danych.

Trwałe przechowywanie stanu aplikacji po stronie klienta

  • Trwałość localStorage: dane zapisane w kluczu tekstowym przetrwają zamknięcie karty, restart przeglądarki i ponowne uruchomienie systemu.
  • Izolacja sesji w sessionStorage: dane przechowywane w sessionStorage ulegają automatycznemu skasowaniu po zamknięciu bieżącej karty.
  • Format danych tylko jako string: wartości złożone (obiekty, tablice) muszą być przed zapisem zserializowane funkcją JSON.stringify().
  • Zagrożenia bezpieczeństwa i XSS: w localStorage nie wolno przechowywać wrażliwych tokenów uwierzytelniających z powodu ryzyka kradzieży przez XSS.
Web Storage API: mechanizm przeglądarki umożliwiający aplikacjom internetowym bezpieczne przechowywanie danych w parach klucz-wartość w pamięci trwałej (localStorage) lub sesyjnej (sessionStorage). Oferuje znacznie większą pojemność niż pliki cookies (zazwyczaj do 5 MB).
// Zapisz (obiekt trzeba stringify)
localStorage.setItem('motyw', 'ciemny');

// Odczytaj
const motyw = localStorage.getItem('motyw');
console.log(motyw);

// Usuń
localStorage.removeItem('motyw');

Źródło: MDN Web Docs - JavaScript Language Guide

47/50
Format JSON: serializacja i deserializacja
Slajd omawia konwersję pomiędzy obiektami JavaScript a formatem JSON za pomocą metod JSON.stringify() oraz JSON.parse().

Uniwersalny standard tekstowej wymiany danych w internecie

  • Format JSON (JavaScript Object Notation): lekki, tekstowy i czytelny dla człowieka format oparty na podzbiorze składni obiektów JS.
  • Metoda JSON.stringify(): dokonuje serializacji obiektu lub tablicy do zunifikowanego łańcucha znaków JSON.
  • Metoda JSON.parse(): przeprowadza deserializację łańcucha JSON z powrotem do natywnego drzewa obiektów w pamięci RAM.
  • Bezpieczeństwo parsowania: nieprawidłowo sformatowany łańcuch rzuca wyjątek SyntaxError, co wymaga zabezpieczenia blokiem try...catch.
JSON (JavaScript Object Notation): niezależny od języka, zwięzły format wymiany danych oparty na parach atrybut-wartość oraz uporządkowanych listach. Stanowi powszechny standard komunikacji pomiędzy przeglądarkami a serwerami w architekturze REST API.
const userObj = { id: 1, name: 'Adam' };

// Serializacja
const userJSON = JSON.stringify(userObj); 

// Zapisz string
localStorage.setItem('user', userJSON);

// Deserializacja
const user = JSON.parse(localStorage.getItem('user'));
console.log(user.name);

Źródło: MDN Web Docs - JavaScript Language Guide

48/50
Zegary w JavaScript: setTimeout i setInterval
Slajd przedstawia metody planowania wykonania zadań z wykorzystaniem API zegarów przeglądarki oraz zwalnianie uchwytów timerów.

Opóźnianie i cykliczne powtarzanie operacji w czasie

  • Funkcja setTimeout(): planuje jednorazowe wykonanie wskazanej funkcji po upływie określonej liczby milisekund.
  • Funkcja setInterval(): uruchamia funkcję cyklicznie w stałych odstępach czasu aż do momentu jej jawnego zatrzymania.
  • Czyszczenie timerów (clearTimeout): anulowanie zaplanowanego zadania za pomocą identyfikatora ID zapobiega wyciekom pamięci.
  • Niedokładność zegara: rzeczywisty czas uruchomienia może być opóźniony przez inne operacje obciążające główny wątek pętli zdarzeń.
Web Timer API: interfejs środowiska przeglądarki udostępniający metody planowania asynchronicznego wykonania kodu po zadanym czasie. Operacje timerów są obsługiwane w kolejce makrozadań przez mechanizm pętli zdarzeń.
const timerID = setTimeout(() => {
    console.log('Jednorazowe opóźnienie');
}, 1500);

// Anulowanie timera przed wykonaniem
clearTimeout(timerID);

// Interwał
let intervalID = setInterval(() => {
    console.log('Co sekundę...');
}, 1000);
clearInterval(intervalID);

Źródło: MDN Web Docs - JavaScript Language Guide

49/50
Geolocation API: uprawnienia i współrzędne
Slajd omawia pobieranie współrzędnych GPS z poszanowaniem prywatności użytkownika i asynchronicznym modelem zgody.

Odczyt położenia geograficznego urządzenia w przeglądarce

  • Wymóg zgody użytkownika: przeglądarka wyświetla systemowe zapytanie o dostęp do lokalizacji; brak zgody wywołuje błąd uprawnień.
  • Metoda getCurrentPosition(): asynchronicznie pobiera bieżące koordynaty (szerokość, długość geograficzną oraz dokładność pomiaru).
  • Wymóg bezpiecznego połączenia HTTPS: ze względów bezpieczeństwa Geolocation API działa wyłącznie na stronach serwowanych przez protokół HTTPS.
  • Śledzenie ruchu z watchPosition(): umożliwia rejestrowanie ciągłych zmian położenia w aplikacjach nawigacyjnych i sportowych.
Geolocation API: wysokopoziomowy interfejs programistyczny przeglądarki umożliwiający aplikacjom internetowym odczyt fizycznej lokalizacji urządzenia na podstawie sygnałów GPS, stacji bazowych sieci komórkowych lub adresacji sieci Wi-Fi.
if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(
        (position) => {
            console.log('Lat:', position.coords.latitude);
            console.log('Lon:', position.coords.longitude);
        },
        (error) => {
            console.error('Błąd Geolokacji:', error.code);
        }
    );
} else {
    console.log("Geolokalizacja nie jest wspierana.");
}

Źródło: MDN Web Docs - JavaScript Language Guide

50/50
Podsumowanie: architektura i rozwój front-endu
Slajd syntetyzuje wiedzę o ekosystemie HTML/CSS/JavaScript oraz wskazuje dalsze kierunki rozwoju w inżynierii webowej.

Synteza wiedzy o technologiach WWW i ścieżka rozwoju inżyniera

  • Trójca technologii WWW: pełna synergia semantyki HTML5, estetyki CSS3 oraz dynamicznej logiki JavaScript ES6+.
  • Bezpieczeństwo aplikacji: stosowanie textContent przeciw XSS, rygorystyczna walidacja danych oraz ochrona pamięci podręcznej.
  • Wzorzec TypeScript: naturalne rozszerzenie JavaScriptu o statyczne typowanie eliminujące błędy już na etapie kompilacji.
  • Architektury komponentowe: opanowanie fundamentów DOM i zdarzeń ułatwia przyswojenie nowoczesnych bibliotek takich jak React czy Vue.
Nowoczesny Front-end: dziedzina inżynierii oprogramowania odpowiedzialna za budowę interfejsów użytkownika, logiki prezentacji oraz integracji z API w środowisku przeglądarek internetowych. Opiera się na solidnych fundamentach standardów sieciowych i nieustannym doskonaleniu architektury kodu.
<!-- Nowoczesny Ekosystem Front-end -->
HTML5 (Semantyka i a11y)
  +-- CSS3 (Układy Flexbox & Grid, RWD)
        +-- JavaScript ES6+ (DOM, Zdarzenia, Async/Await)
              +-- TypeScript & Frameworki SPA (React, Vue, Angular)

Źródło: MDN Web Docs - JavaScript Language Guide