JS: Anonüümsed funktsioonid

Javascript pakub erinevaid viise funktsioonide loomiseks ja kasutamiseks. Üks neist on klassikalised funktsioonid, mida vaatlesime eelmises peatükis. Klassikalised funktsioonid on nimetatud funktsioonid, mis võivad võtta argumente, omada keha ja tagastada väärtusi. Neid funktsioone saab defineerida ja kutsuda, et täita konkreetseid ülesandeid või teostada teatud arvutusi.

Anonüümsed funktsioonid

// Anonüümse funktsiooni näide
var tervita = function() {
  console.log("Tere maailm!");
};

// Anonüümse funktsiooni kutsumine
tervita();
var summa = function(a, b) {
  return a + b;
};

var tulemus = summa(3, 5);
console.log(tulemus); // Väljund: 8

Anonüümseid funktsioone saab kasutada argumentidena teistele funktsioonidele, näiteks sündmuste käitlemiseks või ajaliste viivituste loomiseks.

// Anonüümne funktsioon koos argumendiga
setTimeout(function() {
    console.log("Tere pärastlõunast!");
}, 1000);
var array = [1, 2, 3, 4, 5];

array.forEach(function(element) {
    console.log(element);
});
const array = [1, 2, 3, 4, 5];

array.forEach(function(element, index, array) {
  console.log("Element:", element);
  console.log("Index:", index);
  console.log("Array:", array);
});

IIFE (Immediately Invoked Function Expression)

IIFE on nimetatud selle järgi, kuidas see kohe pärast loomist kohe välja kutsutakse.

(function() {
  var x = 10;
  console.log(x); // Output: 10
})();

Noolefunktsioonid

Noolefunktsioon (arrow function) – see on anonüümse funktsiooni alaliik Javascriptis. Noolefunktsioonid on lihtsustatud süntaksiga funktsioonid, mis kasutavad nooleoperaatorit (=>) funktsioonikeha defineerimiseks.

const noolFunktsioon= () => {
  // funktsiooni keha
};

const noolFunktsioon = () => {
  console.log("Tere noolfunktsioon!")
};

// Kui funktsiooni kehas on ainult üks avaldus, siis saame isegi loogelised sulud {} ära jätta.

const noolFunktsioon = () => console.log("Tere noolfunktsioon!");
noolFunktsioon();

Ja argumentidega ja massiiviga funktsiooni näited

//noolefunktsioon argumentidega
let tervita = (nimi) => {console.log(`Tere ${nimi}`)};
tervita("Juhan");

//noolefunktsioon lihtsustatud - KUI ARGUMENTE ON ÜKS, SIIS VÕIB KA NEED SULUD ÄRA JÄTTA
let tervita2 = nimi => console.log(`Tere ${nimi}`);
tervita2("Mari");

//kui kehas on rohkem ridu, siis sulud jäävad
let liitmine = (a, b) => {
  let result = a + b;
  return result;
};
console.log(liitmine(3,5));

//noolefunktsioon lihtsustatud argumentidega
let liitmine = (a, b) => a + b;
console.log(liitmine(3,5));

//noolefunktsioon ja massiviist elementide kuvamine
const array = [1, 2, 3, 4, 5];
array.forEach(element => console.log(element));

Eriti läheb huvitavamaks, kui lisada mitu lühendatud koodi kokku. Näiteks funktsioon, mis leiab kas arv on paaris või paaritu

const number = 5;
const isEven = number => number % 2 === 0 ? "paaris" : "paaritu";

console.log(isEven(number)); // Väljund: paaritu

Ja sama näide massiivi korral

const arvud = [1, 2, 3, 4, 5];

arvud.forEach(nr => {
  const paaris = nr % 2 === 0 ? "paaris" : "paaritu";
  console.log(`${nr} is ${paaris}`);
});

Noolefunktsioone ei saa kasutada kui:

  1. Konstruktorifunktsioonides – noolefunktsioonidel puudub this sidumine, seega neid ei saa kasutada objektide loomisel konstruktorifunktsioonide kaudu. Konstruktorifunktsioonid vajavad this sidumist, et luua uus objekt ja seada selle omadused.
  2. Meetoditena objektidel – kui soovite luua meetodit, mis kasutab this viidet objekti enda kontekstile, siis noolefunktsioone ei saa kasutada. Noolefunktsioonid pärib this väärtuse ümbritsevast kontekstist, mitte sellest objektist, kus neid kasutatakse.
  3. Prototüüpimeetoditena – kui soovite lisada noolefunktsiooni prototüübi meetodina, siis see ei päri õiget this sidumist ega viita õigele objektile.

Tagasikutsumisfunktsioon (Callbacks)

Tegelikult eespool näidetes me seda forEach puhul kasutasime, aga selguse huvides vaatame uuesti üle. Javascripti forEach meetod võtab vastu callback-funktsiooni argumendina ja seejärel kutsub seda funktsiooni iga massiivi elemendi jaoks.

let nimed = ["Kati", "Marta", "Andres", "Jüri", "Liisa"];

nimed.forEach(function(nimi) {
  console.log(`<li>${nimi}</li>`);
});

Võime funktsiooni ka eraldi luua ja siis selle välja kutsuda.

let nimed = ["Kati", "Marta", "Andres", "Jüri", "Liisa"];

const kasutaja = function(nimi) {
  console.log(`<li>${nimi}</li>`);
};

nimed.forEach(kasutaja);

Ja veel parem, me saame selle panne kirja noolefunktsioonina

let nimed = ["Kati", "Marta", "Andres", "Jüri", "Liisa"];

//pikalt
const kasutaja = nimi => console.log(`<li>${nimi}</li>`);
nimed.forEach(kasutaja);

//lühidalt
nimed.forEach(nimi => console.log(`<li>${nimi}</li>`));

Näide lihtsast AJAX API päringust koos callback-funktsiooniga, kasutades noolefunktsiooni.

const teostaAJAXPäring = (url, callback) => {
  setTimeout(() => {
    const vastus = "Vastus andmebaasist";
    callback(vastus);
  }, 2000);
};

const callbackFunktsioon = (vastus) => {
  console.log("Vastus saadud:", vastus);
};

teostaAJAXPäring("https://api.example.com/data", callbackFunktsioon);

Ülesanne

1. Erinevad funktsioonid
Koosta kaks funktsiooni, mis väljastavad sinu nime (ilma ühegi argumendita). Kasuta klassikaslist ja noolefunktsioone.

    function minuNimi() {
        console.log("Minu nimi on Artjom");
    }
    minuNimi();
    
    const minuNimi2 = () => console.log("Minu nimi on Artjom");
    minuNimi2();
    

    2. Argumendiga funktsioon
    Kirjuta funktsioon nimega `kuupaevEesti`, mis kuvab konsoolile praeguse kuupäeva ja kuu eesti keeles. Argumendiks kuupäev kujul 19.07.25

    function kuupaevEesti(kuupaev) {
        const kuud = [
            "jaanuar", "veebruar", "märts", "aprill", "mai", "juuni",
            "juuli", "august", "september", "oktoober", "november", "detsember"
        ];
    
        let split = kuupaev.split(".");
        let paev = split[0];
        let kuu = split[1];
        let aasta = split[2];
        let kuuNimi = kuud[parseInt(kuu) - 1];
    
        console.log(`${parseInt(paev)}. ${kuuNimi} 20${aasta}`);
    }
    
    kuupaevEesti("19.07.25");
    

    3.Teadmata hulk
    Kirjuta funktsioon, mis võtab siseniks kasutajalt teadmata hulga täisarve ning tagastab nende koguarvu ning keskmise.

    function arvuta(...arvud) {
        let kogusumma = 0;
        for (let i = 0; i < arvud.length; i++) {
            kogusumma += arvud[i];
        }
    
        let keskmine = 0;
        if (arvud.length > 0) {
            keskmine = kogusumma / arvud.length;
        }
    
        return { "kogusumma": kogusumma, "keskmine": keskmine };
    }
    
    console.log(arvuta(3, 5, 7, 10));
    
    

    4. Salajane sõnum
    Kirjuta noolefunktsioon nimega salajaneSonum, mis võtab sisendiks sõnumi stringi ning tagastab selle sõnumi põhjal salajase versiooni. Salajase versiooni loomiseks asendatakse kõik täishäälikud (vokaalid) tärniga (*), jättes konsonandid muutumatuks.

    const salajaneSonum = (sonum) => {
        const taishaalikud = ["a", "e", "i", "o", "u", "õ", "ä", "ö", "ü",
            "A", "E", "I", "O", "U", "Õ", "Ä", "Ö", "Ü"];
    
        let tulemus = "";
        for (let i = 0; i < sonum.length; i++) {
            const taht = sonum[i];
            if (taishaalikud.includes(taht)) {
                tulemus += "*";
            } 
            else {
                tulemus += taht;
            }
        }
        return tulemus;
    };
    
    console.log(salajaneSonum("Tere maailm!"));
    
    

    5. Unikaalsed nimed
    Kirjuta noolefunktsioon nimega leiaUnikaalsedNimed, mis võtab sisendiks massiivi erinevatest nimedest ning tagastab uue massiivi, kus on ainult unikaalsed nimed esialgses järjekorras. See tähendab, et kui esineb mitu sama nime, siis tuleb need jätta ainult esinemise esialgsesse kohta ja eemaldada ülejäänud koopiad.
    ["Kati", "Mati", "Kati", "Mari", "Mati", "Jüri"]

    const leiaUnikaalsedNimed = nimed =>
        nimed.filter((nimi, index) => nimed.indexOf(nimi) === index);
    
    const nimed = ["Kati", "Mati", "Kati", "Mari", "Mati", "Jüri"];
    console.log(leiaUnikaalsedNimed(nimed));