# JavaScript funksional dasturlash asoslari

> Sof funksiya, immutability, yuqori tartibli funksiyalar, kompozitsiya, currying va memoizatsiya. Yon ta'sirsiz kod yozishni amalda o'rganing.

Manba: https://learncode.uz/javascript/funksional-dasturlash/
Sana: 2026-06-07

[Massiv metodlari](https://learncode.uz/javascript/massiv-metodlari) va
[arrow funksiyalar](https://learncode.uz/javascript/arrow-funksiyalar) — funksional uslubning
bir qismi. Bu darsda uning tamoyillari va nima uchun kodni ishonchli
qilishini ko'ramiz.

## Sof funksiya

```js
// Sof: bir xil kirish → bir xil chiqish, outer olamga tegmaydi
function addPure(a, b) {
  return a + b;
}

console.log(addPure(2, 3));
console.log(addPure(2, 3));

// Nosof: tashqi holatga bog'liq va uni o'zgartiradi
let total = 0;
function addImpure(n) {
  total += n;
  return total;
}

console.log(addImpure(5));
console.log(addImpure(5));
```

Nosof funksiya bir xil argument bilan **turli** natija berdi — chunki u
tashqi `total` ga bog'liq.

> **Atama**
>
> **Sof funksiya** (pure function) ikki shartga javob beradi: bir xil kirishda
> har doim bir xil natija qaytaradi va **yon ta'siri** yo'q — tashqi
> o'zgaruvchini, DOM'ni yoki faylni o'zgartirmaydi.
>
> **Yon ta'sir** (side effect) — funksiyaning qaytarish qiymatidan tashqari
> har qanday ta'siri: `console.log`, tarmoq so'rovi, global o'zgaruvchini
> o'zgartirish.

Sof funksiyaning foydasi: sinash oson (faqat kirish va chiqish),
natijasini keshlash mumkin, va tartibini o'zgartirish xavfsiz.

## O'zgartirmaslik (immutability)

```js
const original = [3, 1, 2];

// O'zgartiradigan metodlar
const copy1 = [...original];
copy1.push(4);
copy1.sort();

console.log("asl:", original);
console.log("copy:", copy1);

// O'zgartirmaydigan yozuv
const extended = [...original, 4];
const sorted = [...original].sort((a, b) => a - b);
const filtered = original.filter((n) => n > 1);

console.log("asl hali ham:", original);
console.log(extended, sorted, filtered);
```

| O'zgartiradi | O'zgartirmaydi |
|---|---|
| `push`, `pop`, `shift`, `unshift` | `[...massiv, yangi]` |
| `splice` | `slice`, `filter` |
| `sort`, `reverse` | `[...massiv].sort()`, `toSorted()` |

Obyektlar uchun ham xuddi shunday:

```js
const student = { name: "Aziz", score: 85 };

// O'zgartiradi
// student.score = 90;

// Yangi obyekt qaytaradi
const updated = { ...student, score: 90 };

console.log(student);
console.log(updated);
console.log(student === updated);
```

## Yuqori tartibli funksiyalar

> **Atama**
>
> **Yuqori tartibli funksiya** (higher-order function) — funksiyani argument
> sifatida qabul qiladigan yoki funksiya qaytaradigan funksiya. `map`, `filter`
> va [closure](https://learncode.uz/javascript/scope-closure) darsidagi `multiplier` — shunday.

```js
// Funksiya qabul qiladi
function applyTwice(action, value) {
  return action(action(value));
}

console.log(applyTwice((n) => n * 3, 2));

// Funksiya qaytaradi
function multiplier(n) {
  return (num) => num * n;
}

const timesFive = multiplier(5);
console.log(timesFive(10));
```

## Kompozitsiya

Kichik funksiyalarni ulab, kattasini yasash:

```js
const trim = (s) => s.trim();
const lower = (s) => s.toLowerCase();
const dashed = (s) => s.replaceAll(" ", "-");

// Qo'lda ulash — ichma-ich, o'ngdan chapga o'qiladi
console.log(dashed(lower(trim("  Salom Dunyo  "))));

// Kompozitsiya yordamchisi — chapdan o'ngga
const pipe = (...amallar) => (value) =>
  amallar.reduce((result, action) => action(result), value);

const makeSlug = pipe(trim, lower, dashed);

console.log(makeSlug("  Salom Dunyo  "));
console.log(makeSlug("  JavaScript Darslari  "));
```

`ulash` funksiyasi `reduce` ustiga qurilgan: har amal oldingisining
natijasini oladi. Natija — o'qiladigan, qayta ishlatiladigan zanjir.

## Currying

```js
// Oddiy
function add(a, b, c) {
  return a + b + c;
}
console.log(add(1, 2, 3));

// Curried
const addCurried = (a) => (b) => (c) => a + b + c;
console.log(addCurried(1)(2)(3));

// Foydasi: qisman qo'llash
const fromTen = addCurried(10);
const fromTenAndFive = fromTen(5);

console.log(fromTenAndFive(1));
console.log(fromTenAndFive(2));
```

> **Atama**
>
> **Currying** — ko'p argumentli funksiyani bir argumentli funksiyalar zanjiriga
> aylantirish. **Qisman qo'llash** (partial application) — argumentlarning bir
> qismini oldindan berib, qolganini kutadigan funksiya olish.

## Amaliy misol

```js
const students = [
  { name: "Aziz", score: 85, group: "IT-21" },
  { name: "Dilnoza", score: 92, group: "IT-20" },
  { name: "Bobur", score: 45, group: "IT-21" },
  { name: "Nodira", score: 78, group: "IT-21" },
];

const byGroup = (g) => (t) => t.group === g;
const scoreAtLeast = (n) => (t) => t.score >= n;
const take = (key) => (t) => t[key];

const result = students
  .filter(byGroup("IT-21"))
  .filter(scoreAtLeast(60))
  .map(take("name"));

console.log(result);

const average = students.reduce((s, t) => s + t.score, 0) / students.length;
console.log("O'rtacha ball:", average.toFixed(1));
```

Har qadam nomlangan va alohida sinaladi. Zanjir yuqoridan pastga o'qiladi va
asl massivga tegmaydi.

## Memoizatsiya

Sof funksiya natijasini keshlash xavfsiz — kirish bir xil bo'lsa, natija ham
bir xil:

```js
function memoize(action) {
  const cache = new Map();

  return (n) => {
    if (cache.has(n)) {
      console.log("  keshdan:", n);
      return cache.get(n);
    }
    const result = action(n);
    cache.set(n, result);
    return result;
  };
}

const heavyCalc = memoize((n) => {
  let s = 0;
  for (let i = 0; i < n * 100000; i++) s += i;
  return s;
});

console.log(heavyCalc(10));
console.log(heavyCalc(10));
console.log(heavyCalc(20));
```

[Map](https://learncode.uz/javascript/set-map) va [closure](https://learncode.uz/javascript/scope-closure) birga —
ikkinchi chaqiruvda hisob qaytarilmadi.

## Qachon ishlatmaslik

> **Aql bilan**
>
> Funksional uslub — vosita, aqida emas. `for` sikli ba'zan `reduce` dan
> o'qishga osonroq, va har bir amalni curried qilish kodni chalkashtiradi.
>
> Amaliy qoida: **sof funksiya** va **o'zgartirmaslik** — deyarli har doim
> foydali. Currying va murakkab kompozitsiya — faqat takrorlanish haqiqatan
> ko'p bo'lganda.

## Amaliy mashq

1. Nosof funksiyani sof qilib qayta yozing;
2. massivni `push` o'rniga spread bilan kengaytiring;
3. obyekt xossasini o'zgartirmasdan yangi nusxa yasang;
4. funksiya qaytaradigan funksiya yozing;
5. `ulash` bilan uch amalni zanjirlang;
6. `keshla` yordamchisini yozib, ikki marta chaqiring.

## Qisqacha xulosa

- **Sof funksiya**: bir xil kirish → bir xil chiqish, yon ta'sirsiz.
- **O'zgartirmaslik**: asl ma'lumotga tegmay, yangi nusxa qaytarish.
- `push`/`sort` o'zgartiradi — `[...massiv]` bilan nusxa oling.
- **Yuqori tartibli funksiya** funksiyani oladi yoki qaytaradi.
- **Kompozitsiya** kichik funksiyalarni zanjirga ulaydi.
- Sof funksiya natijasini keshlash xavfsiz (**memoizatsiya**).

Keyingi darsda [Proxy va Reflect](https://learncode.uz/javascript/proxy-reflect) — obyekt
xatti-harakatini boshqarish.
