0%

⚙️ Funkcijas

Funkcijas ir atkārtoti izmantojami koda bloki. JavaScript funkcijas ir "pirmās klases objekti" – tās var glabāt mainīgajos, padot kā argumentus un atgriezt no citām funkcijām.

javascript

Funkcijas deklarācija vs izteiksme

Teksts
// ======================================
// 1. Funkcijas deklarācija (declaration)
// ======================================
// Tiek "paaugstināta" (hoisted) – var izsaukt pirms definīcijas!
sveicināt("Anna"); // "Sveiki, Anna!" ← strādā pirms definitions

function sveicināt(vārds) {
    return "Sveiki, " + vārds + "!";
}

// ======================================
// 2. Funkcijas izteiksme (expression)
// ======================================
// NAV hoisted – jāizsauc pēc piešķiršanas
const summa = function(a, b) {
    return a + b;
};
console.log(summa(3, 4)); // 7

// Nosaukta funkcijas izteiksme (noderīga rekursijai)
const faktoriāls = function fakt(n) {
    return n <= 1 ? 1 : n * fakt(n - 1);
};

// ======================================
// 3. Bultiņu funkcija (arrow function)
// ======================================
const reizināt = (a, b) => a * b;         // Viena izteiksme
const kvadrāts = n => n ** 2;              // Viens parametrs, nav ()
const konstante = () => 42;                // Nav parametru
const sarežģīts = (a, b) => {             // Ar bloku
    const rezultāts = a * b;
    return rezultāts + 1;
};

// ======================================
// Salīdzinājums
// ======================================
function parastā(x) { return x * 2; }
const izteiksme = function(x) { return x * 2; };
const bultiņa = x => x * 2;

// Visi rezultāti vienādi!
console.log(parastā(5));   // 10
console.log(izteiksme(5)); // 10
console.log(bultiņa(5));   // 10

Parametri un noklusējuma vērtības

Teksts
// Noklusējuma parametri (ES2015)
function sveicināt(vārds = "Viesis", valoda = "lv") {
    const sveicieni = {
        lv: `Sveiki, ${vārds}!`,
        en: `Hello, ${vārds}!`,
        de: `Hallo, ${vārds}!`,
    };
    return sveicieni[valoda] ?? sveicieni.lv;
}

sveicināt();             // "Sveiki, Viesis!"
sveicināt("Anna");       // "Sveiki, Anna!"
sveicināt("John", "en"); // "Hello, John!"

// ======================================
// Rest parametri (...args)
// ======================================
function saskaitīt(...skaitļi) {
    return skaitļi.reduce((s, n) => s + n, 0);
}
saskaitīt(1, 2, 3, 4, 5); // 15

function pirmaisSumma(pirmais, ...pārējie) {
    const summa = pārējie.reduce((s, n) => s + n, 0);
    return `Pirmais: ${pirmais}, Summa: ${summa}`;
}
pirmaisSumma(10, 1, 2, 3); // "Pirmais: 10, Summa: 6"

// ======================================
// Objekta destrukturizācija kā parametrs
// ======================================
function izveidotKarti({ vārds, vecums, pilsēta = "nav norādīta" }) {
    return `${vārds} (${vecums}g.) – ${pilsēta}`;
}
izveidotKarti({ vārds: "Anna", vecums: 28, pilsēta: "Rīga" });
// "Anna (28g.) – Rīga"

izveidotKarti({ vārds: "Jānis", vecums: 35 });
// "Jānis (35g.) – nav norādīta"

Augstākas kārtas funkcijas

Teksts
// Funkcija, kas pieņem citu funkciju kā argumentu
function pielietotDivreiz(funkcija, vērtība) {
    return funkcija(funkcija(vērtība));
}

const divreizPievieno = x => x + 2;
pielietotDivreiz(divreizPievieno, 5); // 9 (5+2+2)

// Funkcija, kas atgriež funkciju
function izveidotSkaitlī(koeficients) {
    return (skaitlis) => skaitlis * koeficients;
}

const divreizāk = izveidotSkaitlī(2);
const trīsreizāk = izveidotSkaitlī(3);

divreizāk(5);   // 10
trīsreizāk(5);  // 15

// Currying – funkcija ar vairākiem pieteikumiem secīgi
const pieskaitīt = a => b => a + b;
const pieskaitīt5 = pieskaitīt(5);
pieskaitīt5(3);   // 8
pieskaitīt5(10);  // 15

// Izmantošana masīvos
const skaitļi = [1, 2, 3, 4, 5];
skaitļi.map(divreizāk);     // [2, 4, 6, 8, 10]
skaitļi.map(pieskaitīt(10));// [11, 12, 13, 14, 15]

Closure (noslēgumi)

Teksts
// Closure – funkcija "atceras" savu izveides vidi
function izveidotSkaitītāju(sākotnējā = 0) {
    let skaits = sākotnējā; // Privātā stāvoklis

    return {
        increment:  () => ++skaits,
        decrement:  () => --skaits,
        reset:      () => { skaits = sākotnējā; },
        iegūt:      () => skaits,
    };
}

const A = izveidotSkaitītāju(0);
const B = izveidotSkaitītāju(100);

A.increment(); // 1
A.increment(); // 2
B.decrement(); // 99

console.log(A.iegūt()); // 2  (neatkarīgs no B)
console.log(B.iegūt()); // 99

// Memoizācija ar closure
function memoize(fn) {
    const kešatmiņa = {};
    return function(...args) {
        const atslēga = JSON.stringify(args);
        if (atslēga in kešatmiņa) {
            console.log("No kešatmiņas");
            return kešatmiņa[atslēga];
        }
        kešatmiņa[atslēga] = fn(...args);
        return kešatmiņa[atslēga];
    };
}

const lēnaFunkcija = memoize(n => {
    // Sarežģīts aprēķins...
    return n * n;
});
lēnaFunkcija(5); // aprēķina
lēnaFunkcija(5); // "No kešatmiņas"

IIFE un citi modeļi

ℹ️ Bultiņu funkcijas un this

Bultiņu funkcijām (=>) nav sava this – tās izmanto vecākā konteksta this. Tas noderīgi callback funkcijās, bet nedrīkst izmantot kā objektu metodes.

Teksts
// IIFE – Immediately Invoked Function Expression
// Izpilda uzreiz, neaizgūst globālo tvērumu
(function() {
    const privāts = "Šis ir privāts mainīgais";
    console.log(privāts);
})(); // ← uzreiz izsauc

// Bultiņu IIFE
(() => {
    console.log("Bultiņu IIFE");
})();

// Async IIFE (bieži izmantots)
(async () => {
    const atbilde = await fetch("https://api.example.com/dati");
    const dati = await atbilde.json();
    console.log(dati);
})();

// Kompoze (compose) – funkciju apvienošana
const kombinē = (...fns) => x => fns.reduceRight((v, f) => f(v), x);

const pievienot1 = x => x + 1;
const reizinātAr2 = x => x * 2;
const atņemt3 = x => x - 3;

const apstrādāt = kombinē(atņemt3, reizinātAr2, pievienot1);
apstrādāt(5); // atņemt3(reizinātAr2(pievienot1(5)))
              // = atņemt3(reizinātAr2(6))
              // = atņemt3(12)
              // = 9