JS: Anonüümsed funktsioonid | Noolefunktsioonid

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.

Lisaks klassikalistele funktsioonidele on JavaScriptis olemas ka teisi funktsiooni liike. Näiteks anonüümsed funktsioonid ja selle uus versioon noolefunktsioonid.

Anonüümsed funktsioonid:

Anonüümsed funktsioonid on nimetamata funktsioonid, mis luuakse otse koodis ning neid kasutatakse sageli kohapeal, kus neid vaja on. Selle asemel, et funktsioonile anda kindel nimi, luuakse anonüümne funktsioon otse muutujasse, argumendina või atribuudina. Anonüümseid funktsioone saab kasutada mitmel viisil, olenevalt vajadusest. NB! Lõppu lisatakse semikoolon ( ; )

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

// Anonüümse funktsiooni kutsumine
tervita();

Siin on näide anonüümsest funktsioonist argumentide kasutamisel, mis tagastab summa kahe arvu vahel:

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);

Anonüümseid funktsioone saab kasutada massiivi elementide kuvamiseks mitmel erineval viisil. Näiteks forEach meetodi kasutamine:

var array = [1, 2, 3, 4, 5];

array.forEach(function(element) {
  console.log(element);
});

forEach meetod võib vastu võtta ka teisi parameetreid, näiteks indeksi või massiivi ennast:

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);
});

Eeliste osas võib öelda, et anonüümsed funktsioonid pakuvad paindlikkust ja lihtsust, eriti olukordades, kus on vaja luua väikesi, ühekordseid funktsioone. Neil on oluline roll ka sündmustepõhises programmeerimises ja asünkroonsetes operatsioonides.

Klassikalised funktsioonid pakuvad rohkem struktureeritust ja taaskasutatavust. Neid saab kasutada laiemas kontekstis ja need võimaldavad keerukamaid tüüpi operatsioone, sealhulgas rekursiooni ja objektorienteeritud programmeerimist.

Mõlemad funktsiooni liigid on kasulikud ja nende valik sõltub konkreetsest olukorrast ning arendaja eelistustest. Mõnikord võib olla vaja kasutada nii anonüümseid kui ka klassikalisi funktsioone, et saavutada parim tulemus.

IIFE (Immediately Invoked Function Expression):

IIFE (Immediately Invoked Function Expression) on anonüümse funktsiooni alaliik. IIFE on nimetatud selle järgi, kuidas see kohe pärast loomist kohe välja kutsutakse. IIFE koosneb anonüümsest funktsioonist, mis on ümbritsetud sulgudega. See anonüümne funktsioon on koheselt väljakutsutud, tavaliselt lisades () paare selle järel.
IIFE-d eristatakse teistest anonüümsetest funktsioonidest selle poolest, et neid kutsutakse välja kohe pärast nende loomist, samal real, kus need on defineeritud. See eristab neid tavalistest anonüümsetest funktsioonidest, mis võivad olla defineeritud ilma kohest väljakutsumisteta.

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

Noolefunktsioonid:
Uue Javascripti versiooniga ES6 tutvustati uut lähenemist anonüümsete funktsioonide loomisel – noolefunktsioon (arrow function). See on anonüümse funktsiooni alaliik Javascriptis. Noolefunktsioonid on lihtsustatud süntaksiga funktsioonid, mis kasutavad nooleoperaatorit (=>) funktsioonikeha defineerimiseks.
Noolefunktsioonide eeliseks on lühem ja selgem süntaks ning automaatne sidumine väliskeskkonnaga (this-sidumine). Need võimaldavad kergemini ja loetavamalt kirjutada anonüümseid funktsioone.

Siin on näide noolefunktsioonist:

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

Ehk lihtne tervitus näeks välja järgmine:

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

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):

Tagasikutsumisfunktsioon (callbacks) on viis, kuidas Javascriptis funktsioone teistele funktsioonidele edastada ja need hiljem tagasi kutsuda. See võimaldab teatud sündmuste või tingimuste täitumisel teostada soovitud toiminguid.
Mõtle sellele kui “helistamisele ja tagasihelistamisele”. Sa saad kedagi helistada ja paluda neil midagi teha, ning hiljem nad helistavad sulle tagasi, et anda teada, et ülesanne on täidetud. Tagasikutsumisfunktsioonid toimivad sarnaselt.
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 noolefunktsioon:

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);