⚙️ 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.
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