INF.03 · JavaScript

Funkcje w JavaScript

Jedno obliczenie, wiele wywołań

  • Kod → próba → wniosek
  • DOM i zdarzenia
  • Własny projekt

Po tej lekcji: Oddzielisz obliczenia od prezentacji, użyjesz parametrów i return.

Wejście → obliczenie → wynik

Funkcja nazywa fragment programu. Parametr jest nazwą w definicji, argument konkretną wartością w wywołaniu. return oddaje wynik i kończy funkcję. console.log tylko wypisuje do konsoli; nie zastępuje return. Funkcja bez jawnego return zwraca undefined. Zmienna lokalna nie zaśmieca całego programu.

Deklaracja i funkcja strzałkowa

function oblicz(a,b) { return a+b; } to deklaracja. const oblicz = (a,b) => a+b to funkcja strzałkowa zapisana w stałej; przy klamrach trzeba napisać return. Funkcji w const nie wywołuj przed inicjalizacją. Strzałka nie ma własnego this ani arguments, więc nie jest automatycznym zamiennikiem każdej metody. W naszych prostych callbackach nie korzystamy z this.

Sprawdź samą funkcję

Najpierw policz wynik ręcznie i wywołaj funkcję w konsoli dla zwykłych oraz granicznych danych. Potem połącz ją z formularzem. W kalkulatorze obliczPlan dostaje poprawną sumę w groszach i dodatnią liczbę rat; sprawdzenie tych założeń należy do obsługi formularza. Dzięki temu łatwo testować matematykę osobno.

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

function: parametry, wywołanie i wynik

Funkcja oddziela obliczenie od pokazywania wyniku. W definicji nazywasz dane, w wywołaniu podajesz konkretne wartości.

Podstawowa forma: function nazwa(parametr) { return wynik; }

function-js.jsjavascript
function obliczWartosc(cena, ilosc = 1) {
    const suma = cena * ilosc;
    return suma;
}
const wynik = obliczWartosc(1299, 2);
console.log(wynik);
console.log(obliczWartosc(1299));
Wynik
2598
1299
  1. cena i ilosc to parametry. 1299 i 2 to argumenty, przypisane według kolejności; suma wynosi 2598.
  2. return zwraca wynik i kończy to wywołanie. Dopiero console.log go wypisuje. Bez return otrzymałbyś undefined.
  3. W drugim wywołaniu używamy domyślnej ilości 1. suma jest zmienną lokalną funkcji, nie służy do odczytu poza nią.

Funkcja strzałkowa i callback

Krótka funkcja może oddawać jedno wyrażenie. Callback to funkcja przekazana innej funkcji, aby ta wywołała ją w odpowiednim momencie.

Podstawowa forma: (parametry) => wyrazenie albo (parametry) => { return wynik; }

arrow-js.jsjavascript
const podwoj = liczba => liczba * 2;
const potroj = (liczba) => {
    return liczba * 3;
};
const liczby = [1, 2, 3];
liczby.forEach((liczba) => {
    console.log(podwoj(liczba));
});
console.log(potroj(2));
Wynik
2
4
6
6
  1. Przy jednym parametrze można pominąć nawiasy. Po strzałce bez klamer wyrażenie zostaje zwrócone automatycznie.
  2. Po dodaniu klamer użyj return, jeśli chcesz oddać wynik — sama instrukcja liczba*3 niczego nie zwróci.
  3. forEach to metoda tablicy: wywołuje przekazaną funkcję dla kolejnych elementów. To nie pętla for, więc break nie kończy forEach; do tego wybierz for...of.
  4. Strzałka nie ma własnego this ani arguments. W prostym przykładzie tego nie potrzebujemy, ale nie zamieniaj w ten sposób każdej metody.

reduce i cennik: skąd suma w kalkulatorze?

W projekcie suma nie pojawia się magicznie. Odczytujemy ceny wybranych kursów i dodajemy je do wyniku poprzedniego kroku.

Podstawowa forma: tablica.reduce((dotychczas, element) => nowaWartosc, wartoscPoczatkowa)

reduce-js.jsjavascript
const ceny = { html: 12999, js: 24900 };
const wybrane = ['html', 'js'];
const suma = wybrane.reduce((razem, kod) => razem + ceny[kod], 0);
console.log(suma);
console.log(Math.floor(1000 / 3));
Wynik
37899
333
  1. 0 jest wartością początkową razem. Dla html dodajemy ceny["html"], więc wynik po pierwszym kroku to 12999.
  2. W drugim kroku razem=12999, kod="js", cena=24900; nowy wynik to 37899. ceny[kod] używa aktualnej wartości zmiennej jako klucza obiektu.
  3. Gdy wybrane jest puste, reduce z początkiem 0 oddaje 0. Bez podanej wartości początkowej pusta tablica wywołałaby błąd.
  4. Math.floor zaokrągla liczbę w dół: 1000/3 daje około333.333, po floor otrzymujesz333. Ostatnia rata wyrównuje resztę.

Intl.NumberFormat: liczba i wygląd kwoty

Obliczenia wykonujemy na groszach, a dopiero prezentację formatujemy jako złote. Formatowanie nie zmienia zapisanej sumy.

Podstawowa forma: new Intl.NumberFormat(jezyk, opcje).format(liczba)

intl-js.jsjavascript
const grosze = 12999;
const formatKwoty = new Intl.NumberFormat('pl-PL', {
    style: 'currency',
    currency: 'PLN'
});
console.log(formatKwoty.format(grosze / 100));
  1. new tworzy obiekt formatera. pl-PL wybiera polski zapis liczb; obiekt opcji w {} określa styl walutowy i kod waluty PLN.
  2. format jest metodą utworzonego obiektu. Dostaje 129.99, bo 12999 groszy dzielimy przez100.
  3. Wynik to napis ze zł i polskim separatorem dziesiętnym. Odstęp przed walutą może być nierozdzielający — nie używaj tego napisu do dalszych obliczeń.

Jak czytać pozostałe zapisy w pełnym przykładzie

ZapisZnaczeniePrzykł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)
warunek ? A : BWyraż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.isArray / Number.isIntegerKontrolują kształt tablicy i pełną liczbę; nie wykonują konwersji wejścia.Number.isInteger(Number(pole.value))
Object / klucz dynamicznyObiekt przechowuje nazwane wartości; ceny[kod] używa aktualnego napisu w zmiennej kod jako nazwy właściwości.ceny["html"]
Math.floor / Intl.NumberFormatfloor zaokrągla w dół; NumberFormat tworzy obiekt formatujący do tekstu. Obliczenia finansowe projektu są w groszach.Math.floor(1000 / 3)
addEventListener / preventDefaultPierwsza 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());
&& / || / ??&& 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.

Ta interakcja wymaga włączonego JavaScriptu.

Prześledź kod, potem zmień jedną rzecz

skrypt.jsjavascript
function obliczPlan(suma, raty) {
    const zwykla = Math.floor(suma / raty);
    const ostatnia = suma - zwykla * (raty - 1);
    return { zwykla, ostatnia };
}
const plan = obliczPlan(1000, 3);
console.log(plan.zwykla, plan.ostatnia); // 333, 334
const podwoj = liczba => liczba * 2;
console.log(podwoj(7)); // 14

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: kalkulator kursów i rat

Własny projekt łączy opcje formularza, liczby, warunki i funkcje. Nie jest kopią całego arkusza.

1. HTML: dwa checkboxy kursów i pole liczby rat. Cennik w JS zapisuje 12999 i 24900 groszy. Wybrane elementy wybiera selektor :checked.

2. Number konwertuje tekst; sprawdź pełną liczbę 1–12 i co najmniej jeden kurs. Pętla reduce dodaje ceny wybranych kursów. Równie poprawna jest zwykła pętla for...of.

3. obliczPlan dzieli sumę w groszach, zaokrągla zwykłą ratę w dół i resztę dodaje do ostatniej. Przy sumie 12999 i 3 ratach otrzymasz 4333,4333,4333 groszy. Przy 1000 i 3: 333, 333, 334. Intl.NumberFormat służy tylko do prezentacji.

4. Sprawdź brak wyboru, jeden i dwa kursy, 1 i 12 rat, pustą wartość, 0, 13 i ułamek. Suma rat ma być równa całej cenie. To obliczenie bez odsetek.

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.

Ta interakcja wymaga włączonego JavaScriptu.

Pełny projekt: index.html

kalkulator/index.htmlhtml
<!doctype html>
<html lang="pl">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>
            Kalkulator warsztatów
        </title>
        <link rel="stylesheet" href="styl.css">
        <script src="skrypt.js" defer>
        </script>
    </head>
    <body>
        <main>
            <h1>
                Kalkulator warsztatów
            </h1>
            <p>
                Wybierz zajęcia. Koszt całkowity liczymy w groszach, bez odsetek. Raty są całkowite; ostatnia wyrównuje resztę.
            </p>
            <label>
                <input type="checkbox" name="kurs" value="html">
                HTML · 129,99 zł
            </label>
            <label>
                <input type="checkbox" name="kurs" value="js">
                JavaScript · 249,00 zł
            </label>
            <form id="formularz">
                <label for="raty">
                    Liczba rat (1–12)
                </label>
                <input id="raty" type="number" min="1" max="12" step="1" required value="3">
                <button>
                    Oblicz
                </button>
            </form>
            <p id="wynik" role="status">
            </p>
        </main>
    </body>
</html>

Pełny projekt: skrypt.js

kalkulator/skrypt.jsjavascript
const ceny = { html: 12999, js: 24900 };
const pieniadze = new Intl.NumberFormat('pl-PL', { style: 'currency', currency: 'PLN' });
function obliczPlan(suma, raty) {
    const zwykla = Math.floor(suma / raty);
    return { zwykla, ostatnia: suma - zwykla * (raty - 1) };
}
document.querySelector('#formularz').addEventListener('submit', (zdarzenie) => {
    zdarzenie.preventDefault();
    const pole = document.querySelector('#raty');
    const wybrane = [...document.querySelectorAll('input[name="kurs"]:checked')];
    const raty = Number(pole.value);
    const wynik = document.querySelector('#wynik');
    if (pole.value.trim() === '' || !Number.isInteger(raty) || raty < 1 || raty > 12 || wybrane.length === 0) {
        wynik.textContent = 'Wybierz co najmniej jeden kurs i od 1 do 12 pełnych rat.';
        return;
    }
    const suma = wybrane.reduce((razem, kurs) => razem + ceny[kurs.value], 0);
    const plan = obliczPlan(suma, raty);
    wynik.textContent = `Razem: ${pieniadze.format(suma / 100)}. ` +
        (raty === 1 ? `Jedna rata: ${pieniadze.format(suma / 100)}.` :
        `${raty - 1} rat po ${pieniadze.format(plan.zwykla / 100)}, ostatnia ${pieniadze.format(plan.ostatnia / 100)}.`);
});

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

Wywołaj funkcję dla 1000 groszy i 1,3,12 rat. Sprawdź, czy suma wszystkich rat jest równa 1000.

Oczekiwany rezultat
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ć

  1. Oddzielisz obliczenia od prezentacji, użyjesz parametrów i return.
  2. Umiesz wskazać przyczynę wyniku w kodzie i sprawdzić przypadek graniczny.
  3. 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