# JavaScript scope va closure

> Scope nima: global va blok ko'rinish sohasi, lexical scope, closure qanday ishlaydi va u nima uchun kerak. Amaliy misollar bilan tushuntirilgan.

Manba: https://learncode.uz/javascript/scope-closure/
Sana: 2026-06-03

O'zgaruvchi qayerda ko'rinadi va qachon yo'qoladi? Bu savolga **scope**
javob beradi. Uning ustiga qurilgan **closure** esa JavaScript'dagi eng
kuchli tushunchalardan biri.

## Scope — ko'rinish sohasi

> **Atama**
>
> **Scope** (ko'rinish sohasi) — o'zgaruvchi kod ichida qayerdan murojaat
> qilinishi mumkin bo'lgan hudud. JavaScript'da uch daraja bor: **global**
> (butun fayl), **funksiya** ichi va **blok** ichi (`{ }`).

```js
const global = "hammaga ko'rinadi";

function outer() {
  const inner = "faqat funksiya ichida";
  console.log(global);
  console.log(inner);
}

outer();
console.log(global);

try {
  console.log(inner);
} catch (error) {
  console.log("Xato:", error.message);
}
```

Ichkaridan tashqariga qarash mumkin, teskarisi — yo'q. Bu bir tomonlama
oyna kabi.

## Blok scope — let va const

```js
if (true) {
  let a = "let";
  const b = "const";
  var c = "var";
}

console.log(c);

try {
  console.log(a);
} catch (error) {
  console.log("a:", error.message);
}
```

`let` va `const` **blokda** qamalgan, `var` esa emas — aynan shu sabab
[o'zgaruvchilar](https://learncode.uz/javascript/ozgaruvchilar) darsida `var` tavsiya
qilinmagan edi.

Sikldagi farq yanada aniqroq:

```js
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log("var:", i), 10);
}

for (let j = 0; j < 3; j++) {
  setTimeout(() => console.log("let:", j), 20);
}
```

`var` uchta `3` chiqardi — sikl tugagach barcha callback'lar **bitta**
o'zgaruvchini ko'rdi. `let` esa har aylanish uchun yangi nusxa yaratdi.

## Lexical scope

Funksiya qayerda **yozilganiga** qarab tashqi o'zgaruvchilarni ko'radi —
qayerdan chaqirilganiga emas:

```js
const title = "outer";

function show() {
  console.log(title);
}

function other() {
  const title = "inner";
  show();
}

other();
```

`"outer"` chiqdi: `show` global darajada yozilgan, shuning uchun global
`title` ni ko'radi.

## Closure — yopilma

Endi asosiy g'oya. Funksiya tashqi o'zgaruvchini **eslab qoladi**, hatto
tashqi funksiya tugagandan keyin ham:

```js
function createCounter() {
  let count = 0;

  return function () {
    count++;
    return count;
  };
}

const increment = createCounter();

console.log(increment());
console.log(increment());
console.log(increment());
```

`createCounter` allaqachon tugadi, lekin `count` yo'qolmadi — qaytarilgan
funksiya uni ushlab turibdi. Bu **closure**.

> **Atama**
>
> **Closure** — funksiya va u yaratilgan muhitning birgalikdagi bog'lanishi.
> Funksiya o'zi tug'ilgan joydagi o'zgaruvchilarga kirish huquqini "o'zi bilan
> olib yuradi".

Har chaqiruv **alohida** muhit yaratadi:

```js
function createCounter() {
  let count = 0;
  return () => ++count;
}

const a = createCounter();
const b = createCounter();

console.log(a(), a(), a());
console.log(b());
```

`b` noldan boshladi — `a` bilan hisobi umumiy emas.

## Nima uchun kerak — yopiq ma'lumot

Closure o'zgaruvchini tashqaridan **himoyalaydi**:

```js
function createAccount(initial) {
  let balance = initial;

  return {
    add(amount) {
      if (amount <= 0) return "Noto'g'ri summa";
      balance += amount;
      return balance;
    },
    withdraw(amount) {
      if (amount > balance) return "Mablag' yetarli emas";
      balance -= amount;
      return balance;
    },
    view() {
      return balance;
    },
  };
}

const account = createAccount(1000);

console.log(account.add(500));
console.log(account.withdraw(2000));
console.log(account.view());
console.log(account.balance);
```

Oxirgi qator `undefined` — `balance` ga faqat qaytarilgan uch metod orqali
tegish mumkin. Tekshiruvlarni aylanib o'tib bo'lmaydi.

## Sozlanadigan funksiya yasash

```js
function multiplier(n) {
  return (num) => num * n;
}

const double = multiplier(2);
const triple = multiplier(3);

console.log(double(10));
console.log(triple(10));
```

Bitta shablon — bir nechta tayyor funksiya. Har biri o'z `n` ini eslab
qolgan.

## Bir marta bajariladigan funksiya

```js
function once(action) {
  let done = false;
  let result;

  return (...args) => {
    if (done) return result;
    done = true;
    result = action(...args);
    return result;
  };
}

const greet = once((name) => {
  console.log("Hisoblanmoqda...");
  return "Salom, " + name;
});

console.log(greet("Aziz"));
console.log(greet("Dilnoza"));
```

Ikkinchi chaqiruvda "Hisoblanmoqda" chiqmadi — natija closure'da saqlangan.

## Amaliy mashq

1. Funksiya ichida o'zgaruvchi yaratib, tashqaridan o'qishga urinib ko'ring;
2. `if` bloki ichida `let` va `var` e'lon qilib, farqini kuzating;
3. hisoblagich yaratuvchi funksiya yozing va ikki nusxa oling;
4. closure bilan yopiq `balance` saqlaydigan obyekt tuzing;
5. `multiplier(5)` kabi sozlanadigan funksiya yasang;
6. `var` li siklni `setTimeout` bilan yozib, nega uchta bir xil son
   chiqishini tushuntiring.

6-qadam scope va closure bog'liqligini yaxshi ko'rsatadi.

## Qisqacha xulosa

- **Scope** — o'zgaruvchi ko'rinadigan hudud: global, funksiya, blok.
- Ichkaridan tashqariga ko'rinadi, tashqaridan ichkariga — yo'q.
- `let`/`const` blokda qamaladi, `var` — yo'q.
- **Lexical scope**: funksiya yozilgan joyiga qarab ko'radi.
- **Closure** — funksiya tashqi o'zgaruvchini tugagandan keyin ham eslaydi.
- Closure yopiq ma'lumot va sozlanadigan funksiyalar uchun ishlatiladi.

Keyingi darsda [this kalit so'zi](https://learncode.uz/javascript/this-kalit-sozi) — kontekst
qanday aniqlanishi haqida.
