Kurs TypeScript // lekcja 11 // technik programista
Funkcje — raz napisz, wiele razy użyj
Liczysz punkty po każdej rundzie gry? Zamknij zasady w funkcji. Dzięki temu zmiana punktacji nie oznacza szukania pięciu kopii tego samego wzoru.
Po tej lekcji potrafisz
- Zdefiniujesz funkcję z parametrami i typem wyniku.
- Odróżnisz zwracanie wartości od wypisywania jej w konsoli.
- Wyjaśnisz zasięg zmiennych i przetestujesz funkcję dla kilku danych.
Aktualizacja zasad turnieju
Organizator zmienia premię za wygraną. Jeżeli wzór na punkty występuje w sześciu miejscach, łatwo poprawić tylko pięć. Funkcja daje tej czynności nazwę i jedno miejsce, w którym zapisujesz reguły. Wywołujący dostarcza dane, a funkcja oblicza wynik.
Małe kroki, konkretne efekty
Parametr to miejsce na dane, argument to konkret
Deklaracja opisuje przepis. Samo napisanie funkcji jeszcze jej nie uruchamia. Dopiero nazwa z
nawiasami wywołuje funkcję. Parametr trafienia dostaje przy każdym wywołaniu nową
wartość.
function punkty(trafienia: number): number {
return trafienia * 10;
}
console.log(punkty(3));
console.log(punkty(0));
30
0
Pierwsze : number opisuje wejście, drugie — wynik. return oddaje obliczoną
wartość i kończy to wywołanie. Argument 3 nie zmienia treści funkcji: korzysta z tego
samego przepisu.
Wynik można wykorzystać dalej
Funkcja obliczająca zwraca wynik. Funkcja wyświetlająca wykonuje czynność. void mówi, że
nie obiecujemy użytecznej wartości zwrotnej. Nie jest synonimem „nic się nie dzieje”.
function podwoj(n: number): number {
return n * 2;
}
function oglos(tekst: string): void {
console.log(tekst);
}
const wynik = podwoj(7);
oglos("Punkty: " + wynik);
Punkty: 14
Gdyby podwoj tylko wypisywała liczbę, nie można byłoby użyć jej wyniku w kolejnym
obliczeniu. Typ wyniku może zostać wywnioskowany, ale tutaj zapisujemy go, żeby dobrze widzieć umowę
funkcji.
Punktacja szkolnego turnieju
Wygrana daje 3 punkty, remis 1 punkt, porażka 0. Na razie przyjmujemy nieujemne, całkowite liczby meczów. Obliczenia trzymamy osobno od raportu.
function policzPunkty(wygrane: number, remisy: number): number {
const wynik = wygrane * 3 + remisy;
return wynik;
}
function raport(nazwa: string, punkty: number): void {
console.log(nazwa + ": " + punkty + " pkt");
}
const alfa = policzPunkty(4, 2);
const beta = policzPunkty(3, 0);
raport("Alfa", alfa);
raport("Beta", beta);
console.log("Różnica: " + (alfa - beta));
Alfa: 14 pkt
Beta: 9 pkt
Różnica: 5
Jak program dochodzi do wyniku
- Wywołanie
policzPunkty(4, 2)podstawia 4 za wygrane i 2 za remisy. - Lokalna zmienna
wyniknależy do funkcji. Poza nią korzystamy ze zwróconej wartości zapisanej walfa. - Drugie wywołanie liczy niezależny wynik. Zmienne lokalne obu wywołań nie są wspólne.
- Raport niczego nie liczy. Można zmienić jego wygląd bez ruszania punktacji.
Zanim przejdziesz dalej
Czy po deklaracji funkcji możesz wykonać console.log(wynik), używając jej lokalnej zmiennej?
Sprawdź swoje rozumowanie
Nie. Ta nazwa jest widoczna tylko wewnątrz funkcji. Na zewnątrz zapisz rezultat wywołania, np. const wynikAlfy = policzPunkty(4, 2).
Zmień kod i zobacz, co się stanie
Wczesny return upraszcza reguły
Czasem pewien przypadek można rozstrzygnąć od razu. Zakończ wtedy funkcję, zamiast budować coraz głębsze zagnieżdżenia. Parametr typu number nadal może być ujemny: typ nie zna reguł Twojej gry.
function opisZycia(zycie: number): string {
if (zycie <= 0) {
return "Koniec gry";
}
return "Pozostało: " + zycie;
}
console.log(opisZycia(0));
console.log(opisZycia(25));
Koniec gry
Pozostało: 25
Dla zera pierwszy return kończy wywołanie. Drugi nie zostaje wykonany. Spróbuj wartości -5 i 1, żeby zbadać obie strony granicy.
Gdy wynik zaskakuje
| Pomyłka | Co się dzieje i jak to poprawić |
|---|---|
| Brak nawiasów przy wywołaniu | policzPunkty to sama funkcja. policzPunkty(4, 2) ją uruchamia.
|
| console.log zamiast return | Komunikat widzisz, ale wywołujący nie dostaje obliczonej liczby. |
| Zmienna lokalna użyta poza funkcją | Przekaż potrzebne dane parametrem albo zwróć wynik. Nie naprawiaj tego zmiennymi globalnymi. |
Teraz Twoja kolej
Rozwiązanie jest jedną z możliwości. Zanim je odkryjesz, uruchom własną wersję dla podanych danych i przynajmniej jednego przypadku brzegowego.
Napisz bonus(seria), który daje 5 punktów za każdy dzień serii. Sprawdź 0, 1 i 7 dni. Zakładamy nieujemne liczby całkowite.
Mała podpowiedź
Funkcja ma przyjąć i zwrócić liczbę.
Przykładowe rozwiązanie z wyjaśnieniem
function bonus(seria: number): number { return seria * 5; }
console.log(bonus(0), bonus(1), bonus(7));
0 5 35
Wynik zwracamy, więc można dodać go do punktów podstawowych.
Funkcja cenaBiletu ma zwracać 15 dla ucznia i 25 dla pozostałych osób. Przekaż boolean, a nie tekst „tak”.
Mała podpowiedź
Warunek może od razu zwrócić cenę.
Przykładowe rozwiązanie z wyjaśnieniem
function cenaBiletu(uczen: boolean): number {
if (uczen) { return 15; }
return 25;
}
console.log(cenaBiletu(true), cenaBiletu(false));
15 25
Każda droga kończy się liczbą; nie ma brakującego wyniku.
Policz średnią z tablicy punktów. Ustal umowę: pusta tablica daje 0. Dla [10, 20, 30] oczekujemy 20. Później poznasz sposób oznaczania braku wyniku typem.
Mała podpowiedź
Najpierw obsłuż pustą tablicę, potem sumuj pętlą.
Przykładowe rozwiązanie z wyjaśnieniem
function srednia(punkty: number[]): number {
if (punkty.length === 0) { return 0; }
let suma = 0;
for (const p of punkty) { suma += p; }
return suma / punkty.length;
}
console.log(srednia([10, 20, 30]), srednia([]));
20 0
Warunek chroni przed dzieleniem przez zero. Zwracanie 0 dla braku danych to jawna decyzja zadania.
Co 100 XP gracz awansuje. Dla 0–99 XP ma poziom 1, dla 100–199 poziom 2. Napisz funkcję i sprawdź granice 99, 100, 199, 200. Ujemne XP potraktuj jako 0.
Mała podpowiedź
Math.floor usuwa część ułamkową w dół. Najpierw popraw ujemne dane.
Przykładowe rozwiązanie z wyjaśnieniem
function poziom(xp: number): number {
const poprawneXp = Math.max(0, xp);
return Math.floor(poprawneXp / 100) + 1;
}
for (const xp of [-1, 99, 100, 199, 200]) {
console.log(xp + " XP: " + poziom(xp));
}
-1 XP: 1
99 XP: 1
100 XP: 2
199 XP: 2
200 XP: 3
Testy wartości tuż przed i na granicy awansu wykrywają błąd przesunięcia o jeden.
Co zabierasz do następnej lekcji
- Funkcja dostaje argumenty przez parametry i może oddać wynik przez return.
- void opisuje brak użytecznego wyniku; console.log tylko wyświetla.
- Zmienne lokalne nie są widoczne poza swoim zasięgiem.
Połączenie z przyszłą nauką Angulara: Metody klas i funkcje pomocnicze również potrzebują czytelnych wejść oraz wyników.