Higher Order Functions — funksiyani parametr va qaytish qiymati sifatida

~15 daq · JavaScript · Funksiyalar chuqurroq

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