W poprzedniej lekcji tego kursu JavaScript opisałem pętle jako sposób na ponowne wykorzystanie raz napisanego fragmentu kodu poprzez jego wielokrotne uruchomienie. Tamten sposób ma jednak poważną wadę – jeżeli ten sam fragment kodu będziesz potrzebować także w innym miejscu, musisz go tam skopiować. Tej wady nie mają funkcje. Upraszczając sprawę funkcje w JavaScript jest to sposób na nadanie nazwy fragmentowi swojego skryptu, i możliwość późniejszego odwoływania się do niego z użyciem tej nazwy.

Szkielet funkcji wygląda następująco:

function NazwaFunkcji ( parametry )
{
    instrukcja1;
    instrukcja2;
    ...
}

NazwaFunkcji jest to dowolna nazwa, która powinna spełniać takie same wymogi jak nazwy zmiennych (czyli pierwszym znakiem może być litera lub znak podkreślenia; kolejne znaki nazwy mogą być literą, cyfrą lub znakiem podkreślenia; nazwa nie może też być zarezerwowanym słowem kluczowym). parametry jest to lista nazw parametrów, rozdzielona przecinkami (nazwy parametrów również muszą spełniać wspomniane wcześniej wymagania). Lista parametrów może być pusta (pomiędzy nawiasami okrągłymi wtedy nic nie ma).

W ciele funkcji może być umieszczona dowolna liczba instrukcji. Nawiasy klamrowe są obowiązkowe i nie można ich pominąć, nawet jeżeli funkcja zawiera tylko jedną instrukcję (lub nawet nie zawiera żadnej instrukcji – w pewnych przypadkach takie funkcje które nic nie robią też mogą być przydatne).

Własne funkcje wywołuje się identycznie jak funkcje wbudowane – po prostu podaje się nazwę funkcji i w nawiasach okrągłych wartości parametrów.

Prosta funkcja i jej wywołanie może wyglądać następująco:

function Witaj(imie)
{
    document.write("Witaj, " + imie);
}
 
Witaj("Daniel");

Funkcje mogą też zwracać pewną wartość. Do zwrócenia wartości z funkcji używa się komendy return, po której podaje się wartość która ma zostać zwrócona z funkcji:

function Suma(a, b)
{
    return a + b;
}

Ważną cechą instrukcji return jest to iż powoduje ona natychmiastowe przerwanie wykonywania funkcji i powrót do miejsca w skrypcie z którego funkcja była wywołana. Z tego też powodu możliwe jest także użycie komendy return bez podawania wartości która ma zostać zwrócona z funkcji, co jest użyteczne gdy piszemy funkcję która ma tylko coś zrobić (np. wypisać jakiś napis), ale nie ma zwracać żadnej wartości.

Poniższa funkcja drukuje wszystkie wartości z przedziału określonego parametrami, ale kończy drukować jeżeli przekroczy liczbę 100.

function DrukujLiczby(a, b)
{
    for (n = a; n <= b; ++n)
    {
        if (n >= 100)
            return;
        document.write(n);
    }
}

Iteracja i rekurencja

Iteracja i rekurencja są to dwa sposoby rozwiązywania problemów gdzie występuje konieczność wielokrotnego wykonywania pewnych operacji. Z iteracją mamy do czynienia gdy do rozwiązania problemu jest zastosowana pętla wewnątrz której prowadzone są właściwe obliczenia. Z kolei rekurencja polega na tym że funkcja wywołuje samą siebie, i w ten sposób wykonywane są obliczenia. Oczywiście w tym drugim przypadku należy też pamiętać aby określić warunek kiedy funkcja powinna bezpośrednio zwrócić wartość a nie wywoływać się po raz kolejny. Bez tego obliczenia nie mogłyby się zakończyć!

Poniżej znajdują się dwa przykłady funkcji które liczą wartość silni podanej liczby naturalnej. Dla tych co zapomnieli co to jest silnia przypominam że jest to iloczyn liczb od 1 do n, np. 3! = 1 * 2 * 3 = 6. Dodatkowo 0! = 1.

Pierwsza funkcja liczy silnię w sposób iteracyjny:

function Silnia_I(n)
{
    wynik = 1;
    for (k = 1; k <= n; ++k)
    {
        wynik *= k;
    }
    return wynik;
}

Druga natomiast funkcja robi to samo, ale z wykorzystaniem rekurencji:

function Silnia_R(n)
{
    if (n == 0)
        return 1;
    else
        return n * Silnia_R(n - 1);
}