Higher Order Functions — funksiyani parametr va qaytish qiymati sifatida
Muammodan boshlaylik
Bir xil tuzilishdagi kod, faqat bitta qism o'zgaradi:
// Juft sonlarni filtrlash
const juftlar = [];
for (const n of sonlar) {
if (n % 2 === 0) juftlar.push(n);
}
// Katta sonlarni filtrlash
const kattalar = [];
for (const n of sonlar) {
if (n > 10) kattalar.push(n);
}
Ikkala kod bir xil — faqat shart o'zgaradi. Bu takrorlanishni qanday yo'qotish mumkin? Shartni parametr sifatida berish — Higher Order Functions.
Higher Order Function nima?
Higher Order Function (HOF) — funksiyani parametr sifatida qabul qiladigan yoki funksiya qaytaradigan funksiya.
JavaScript da funksiyalar — oddiy qiymat. Raqam yoki string kabi parametr sifatida beriladi, qaytariladi.
function filtrlash(massiv, shart) { // ← shart — funksiya
const natija = [];
for (const element of massiv) {
if (shart(element)) natija.push(element); // ← funksiyani chaqiradi
}
return natija;
}
const sonlar = [1, 2, 3, 4, 5, 6, 7, 8];
const juftlar = filtrlash(sonlar, n => n % 2 === 0); // [2, 4, 6, 8]
const kattalar = filtrlash(sonlar, n => n > 5); // [6, 7, 8]
Bir funksiya — ikki xil natija. Mantiq ajratildi.
Hayotiy o'xshatma
Taksi parki. Dispetcher — buyurtmalarni qabul qiladi va haydovchilarga beradi. Dispetcher qaysi yo'ldan borishni bilmaydi — haydovchi biladi. Dispetcher faqat "mana buyurtma, sen hal qil" deydi.
HOF — dispetcher. Callback — haydovchi. Umumiy mantiq (buyurtma qabul qilish) va maxsus mantiq (yo'l tanlash) ajratilgan.
Nima uchun shunday?
Nima uchun HOF kerak?
Takrorlanishni kamaytiradi. Bir xil tuzilish — bir marta yoziladi. Faqat o'zgaradigan qism parametr sifatida beriladi.
Kodni kompozitsiyalash imkonini beradi. Kichik funksiyalarni birlashtirish orqali murakkab mantiq quriladi.
const sonlar = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Juft sonlarni topib, ikki barobarga oshirib, yig'indisini hisoblash
const natija = sonlar
.filter(n => n % 2 === 0) // [2, 4, 6, 8, 10]
.map(n => n * 2) // [4, 8, 12, 16, 20]
.reduce((sum, n) => sum + n, 0); // 60
Massivning built-in HOF lari
forEach — har element uchun
const ismlar = ["Ali", "Vali", "Soli"];
ismlar.forEach((ism, index) => {
console.log(`${index + 1}. ${ism}`);
});
// 1. Ali
// 2. Vali
// 3. Soli
forEach — qiymat qaytarmaydi. Faqat yon ta'sir (console, DOM o'zgartirish) uchun.
map — har elementni o'zgartirish
const narxlar = [100, 200, 300];
const chegirmali = narxlar.map(n => n * 0.9); // [90, 180, 270]
map — yangi massiv qaytaradi. Asl massiv o'zgarmaydi.
filter — shartga mos elementlar
const mahsulotlar = [
{ ism: "Olma", narx: 5000 },
{ ism: "Nok", narx: 8000 },
{ ism: "Uzum", narx: 12000 },
];
const arzon = mahsulotlar.filter(m => m.narx < 10000);
// [{ ism: "Olma", narx: 5000 }, { ism: "Nok", narx: 8000 }]
reduce — massivni bitta qiymatga kamaytirish
const sonlar = [1, 2, 3, 4, 5];
const yig'indi = sonlar.reduce((jamlanma, son) => jamlanma + son, 0); // 15
// ↑ to'plangan qiymat ↑ joriy element ↑ boshlang'ich
reduce — eng kuchli, lekin tushunish qiyinroq. Yig'indi, maksimum, ob'ektga aylantirish — hammasi reduce bilan:
// Massivni ob'ektga aylantirish
const foydalanuvchilar = [
{ id: 1, ism: "Ali" },
{ id: 2, ism: "Vali" },
];
const idBoyicha = foydalanuvchilar.reduce((ob'ekt, f) => {
ob'ekt[f.id] = f;
return ob'ekt;
}, {});
// { 1: { id: 1, ism: "Ali" }, 2: { id: 2, ism: "Vali" } }
Funksiya qaytaradigan funksiyalar
HOF ning ikkinchi turi — funksiya qaytaradi. Bu closure bilan birgalikda kuchli pattern:
function logger(prefiks) {
return function(xabar) { // ← funksiya qaytaradi
console.log(`[${prefiks}] ${xabar}`);
};
}
const xato = logger("XATO");
const info = logger("INFO");
xato("Ulanish uzildi"); // [XATO] Ulanish uzildi
info("Server ishga tushdi"); // [INFO] Server ishga tushdi
Tez-tez uchraydigan xatolar
map o'rniga forEach ishlatish:
// ❌ forEach qiymat qaytarmaydi
const ikki_baravar = sonlar.forEach(n => n * 2); // undefined
// ✅ map yangi massiv qaytaradi
const ikki_baravar = sonlar.map(n => n * 2);
reduce da boshlang'ich qiymat unutish:
const sonlar = [1, 2, 3];
sonlar.reduce((sum, n) => sum + n); // 6 — ishlaydi, lekin...
[].reduce((sum, n) => sum + n); // ❌ TypeError — bo'sh massiv!
[].reduce((sum, n) => sum + n, 0); // ✅ 0 — xavfsiz
filter + map o'rniga reduce ishlatish — o'qish qiyinlashadi:
// ❌ bir o'tishda, lekin o'qish qiyin
const natija = sonlar.reduce((acc, n) => {
if (n % 2 === 0) acc.push(n * 2);
return acc;
}, []);
// ✅ ikki o'tish, lekin aniq
const natija = sonlar.filter(n => n % 2 === 0).map(n => n * 2);
Xulosa
Higher Order Function — funksiyani parametr sifatida qabul qiladigan yoki funksiya qaytaradigan funksiya.
forEach — yon ta'sir uchun, qiymat qaytarmaydi.
map — har elementni o'zgartiradi, yangi massiv qaytaradi.
filter — shartga mos elementlarni tanlaydi.
reduce — massivni bitta qiymatga kamaytiradi.
HOF — takrorlanishni kamaytiradi, kodni kompozitsiyalash imkonini beradi.
Keyingi dars
13-dars: Callback funksiyalar