O'zbek

Amaliy misollar orqali JavaScript yopilmalarini (closures) o'rganing, ularning qanday ishlashini va dasturiy ta'minotni ishlab chiqishda real hayotdagi qo'llanilishini tushuning.

JavaScript Yopilmalari (Closures): Amaliy Misollar Bilan Tushuntirish

Yopilmalar (closures) JavaScript-dagi fundamental tushuncha bo'lib, ko'pincha barcha darajadagi dasturchilarda chalkashliklarga sabab bo'ladi. Samarali, qo'llab-quvvatlanadigan va xavfsiz kod yozish uchun yopilmalarni tushunish juda muhimdir. Ushbu keng qamrovli qo'llanma amaliy misollar bilan yopilmalarni tushuntiradi va ularning real hayotdagi qo'llanilishini namoyish etadi.

Yopilma (Closure) nima?

Oddiy qilib aytganda, yopilma - bu funksiya va ushbu funksiya e'lon qilingan leksik muhitning birikmasidir. Bu shuni anglatadiki, yopilma funksiyaga tashqi funksiya o'z ishini tugatgandan keyin ham o'zining atrofidagi ko'lamdan (scope) o'zgaruvchilarga kirish imkonini beradi. Buni ichki funksiyaning o'z muhitini "eslab qolishi" deb tasavvur qiling.

Buni to'liq tushunish uchun asosiy tarkibiy qismlarni ko'rib chiqaylik:

Sehr shundaki, ichki funksiya tashqi funksiya qaytarilgandan keyin ham o'zining leksik ko'lamidagi o'zgaruvchilarga kirish huquqini saqlab qoladi. Bu xususiyat JavaScript-ning ko'lam (scope) va xotirani boshqarish usulining asosiy qismidir.

Nima uchun Yopilmalar Muhim?

Yopilmalar shunchaki nazariy tushuncha emas; ular JavaScript-dagi ko'plab keng tarqalgan dasturlash na'munalari uchun zarurdir. Ular quyidagi afzalliklarni taqdim etadi:

JavaScript Yopilmalarining Amaliy Misollari

Keling, yopilmalarning qanday ishlashini va ularni real hayot stsenariylarida qanday qo'llash mumkinligini ko'rsatish uchun ba'zi amaliy misollarga sho'ng'iymiz.

1-misol: Oddiy Hisoblagich

Ushbu misol funksiya chaqiruvlari o'rtasida o'z holatini saqlaydigan hisoblagichni yaratish uchun yopilmadan qanday foydalanish mumkinligini ko'rsatadi.


function createCounter() {
  let count = 0;

  return function() {
    count++;
    console.log(count);
  };
}

const increment = createCounter();

increment(); // Natija: 1
increment(); // Natija: 2
increment(); // Natija: 3

Tushuntirish:

2-misol: Shaxsiy O'zgaruvchilar Bilan Ma'lumotlar Inkapsulyatsiyasi

Yopilmalar shaxsiy (private) o'zgaruvchilar yaratish uchun ishlatilishi mumkin, bu ma'lumotlarni funksiya tashqarisidan to'g'ridan-to'g'ri kirish va o'zgartirishdan himoya qiladi.


function createBankAccount(initialBalance) {
  let balance = initialBalance;

  return {
    deposit: function(amount) {
      balance += amount;
      return balance; //Namoyish uchun qaytarilmoqda, void bo'lishi mumkin edi
    },
    withdraw: function(amount) {
      if (amount <= balance) {
        balance -= amount;
        return balance; //Namoyish uchun qaytarilmoqda, void bo'lishi mumkin edi
      } else {
        return "Mablag' yetarli emas.";
      }
    },
    getBalance: function() {
      return balance;
    }
  };
}

const account = createBankAccount(1000);

console.log(account.deposit(500)); // Natija: 1500
console.log(account.withdraw(200)); // Natija: 1300
console.log(account.getBalance()); // Natija: 1300

// Balansga to'g'ridan-to'g'ri kirishga urinish ishlamaydi
// console.log(account.balance); // Natija: undefined

Tushuntirish:

3-misol: Siklda `setTimeout` Bilan Yopilmalardan Foydalanish

Yopilmalar asinxron operatsiyalar, masalan, setTimeout bilan ishlashda, ayniqsa sikllar ichida juda muhimdir. Yopilmalarsiz, JavaScript-ning asinxron tabiati tufayli kutilmagan xatti-harakatlarga duch kelishingiz mumkin.


for (var i = 1; i <= 5; i++) {
  (function(j) {
    setTimeout(function() {
      console.log("i ning qiymati: " + j);
    }, j * 1000);
  })(i);
}

// Natija:
// i ning qiymati: 1 (1 soniyadan keyin)
// i ning qiymati: 2 (2 soniyadan keyin)
// i ning qiymati: 3 (3 soniyadan keyin)
// i ning qiymati: 4 (4 soniyadan keyin)
// i ning qiymati: 5 (5 soniyadan keyin)

Tushuntirish:

Siklda var o'rniga let dan foydalanish ham bu muammoni hal qiladi, chunki let har bir iteratsiya uchun blokli ko'lam (block scope) yaratadi.


for (let i = 1; i <= 5; i++) {
  setTimeout(function() {
    console.log("i ning qiymati: " + i);
  }, i * 1000);
}

// Natija (yuqoridagi bilan bir xil):
// i ning qiymati: 1 (1 soniyadan keyin)
// i ning qiymati: 2 (2 soniyadan keyin)
// i ning qiymati: 3 (3 soniyadan keyin)
// i ning qiymati: 4 (4 soniyadan keyin)
// i ning qiymati: 5 (5 soniyadan keyin)

4-misol: Karring (Currying) va Qisman Qo'llash (Partial Application)

Yopilmalar ko'p argumentli funksiyalarni har biri bitta argument qabul qiladigan funksiyalar ketma-ketligiga aylantirish uchun ishlatiladigan karring va qisman qo'llash texnikalari uchun asosiy hisoblanadi.


function multiply(a) {
  return function(b) {
    return function(c) {
      return a * b * c;
    };
  };
}

const multiplyBy5 = multiply(5);
const multiplyBy5And2 = multiplyBy5(2);

console.log(multiplyBy5And2(3)); // Natija: 30 (5 * 2 * 3)

Tushuntirish:

5-misol: Modul Namunasi (Module Pattern)

Yopilmalar modul namunasida keng qo'llaniladi, bu JavaScript kodini tashkil etish va tuzilishga yordam beradi, modullikni oshiradi va nomlar to'qnashuvining oldini oladi.


const myModule = (function() {
  let privateVariable = "Salom, dunyo!";

  function privateMethod() {
    console.log(privateVariable);
  }

  return {
    publicMethod: function() {
      privateMethod();
    },
    publicProperty: "Bu ommaviy xususiyat."
  };
})();

console.log(myModule.publicProperty); // Natija: Bu ommaviy xususiyat.
myModule.publicMethod(); // Natija: Salom, dunyo!

// privateVariable yoki privateMethod'ga to'g'ridan-to'g'ri kirishga urinish ishlamaydi
// console.log(myModule.privateVariable); // Natija: undefined
// myModule.privateMethod(); // Natija: TypeError: myModule.privateMethod funksiya emas

Tushuntirish:

Yopilmalar va Xotirani Boshqarish

Yopilmalar kuchli bo'lsa-da, ularning xotirani boshqarishga potentsial ta'siridan xabardor bo'lish muhimdir. Yopilmalar o'zlarining atrofidagi ko'lamdan o'zgaruvchilarga kirish huquqini saqlab qolganligi sababli, agar bu o'zgaruvchilar endi kerak bo'lmasa, ularning axlat yig'uvchi (garbage collector) tomonidan tozalanishiga to'sqinlik qilishi mumkin. Agar ehtiyotkorlik bilan ishlanmasa, bu xotira oqishiga (memory leaks) olib kelishi mumkin.

Xotira oqishini oldini olish uchun, yopilmalar ichidagi o'zgaruvchilarga keraksiz havolalarni ular endi kerak bo'lmaganda uzishga ishonch hosil qiling. Buni o'zgaruvchilarni null ga tenglashtirish yoki keraksiz yopilmalar yaratishdan qochish uchun kodingizni qayta tuzish orqali amalga oshirish mumkin.

Yopilmalar Bilan Bog'liq Keng Tarqalgan Xatolardan Qochish

Xulosa

JavaScript yopilmalari har bir JavaScript dasturchisi tushunishi kerak bo'lgan kuchli va muhim tushunchadir. Ular ma'lumotlar inkapsulyatsiyasi, holatni saqlash, yuqori tartibli funksiyalar va asinxron dasturlash imkonini beradi. Yopilmalarning qanday ishlashini va ulardan samarali foydalanishni tushunish orqali siz yanada samarali, qo'llab-quvvatlanadigan va xavfsiz kod yozishingiz mumkin.

Ushbu qo'llanma amaliy misollar bilan yopilmalarning keng qamrovli sharhini taqdim etdi. Ushbu misollar bilan mashq qilib va tajriba o'tkazib, siz yopilmalar haqidagi tushunchangizni chuqurlashtirishingiz va yanada malakali JavaScript dasturchisiga aylanishingiz mumkin.

Qo'shimcha O'rganish Uchun

JavaScript Yopilmalari (Closures): Amaliy Misollar Bilan Tushuntirish | MLOG