• 30 ta ko'rildi

Javascript-da IIFE tushunchasi

IIFE (Immediately Invoked Function Expression) - bu darhol chaqiriluvchi funksiya e'lon qilish bo'lib, u JavaScriptda e'lon qilingan paytning o'zidayoq ishga tushadigan funksiya hisoblanadi.

Sintaksisi:

(function (copyOfParam) {
 statements
})(param);

yoki

(() => {
 /* */
})()

Shuningdek u Self-Executing Anonymous Function (O'zini o'zi ishga tushiruvchi anonim funksiya) nomi bilan ham ma'lum bo'lib, dizayn pattern bo'lib hisoblanadi. U 2 ta asosiy qismdan iborat:

  1. Guruhlovchi operator ( () ) ichida berilgan anonim funksiya
  2. Funksiyani Javascript enjin tomonidan ishga tushirishga sabab bo'luvchi funkisya e'lon qiluvchisi ( () )

Ishlatish holatlari:

Global sohada juda ko'p kod yozmaslik kerak. Chunki, proyektimiz har xil tashqi fayllarda e'lon qilingan funksiya va o'zgaruvchilarga ega bo'lishi mumkin. Global o'zgaruvchilarning sonini cheklash doimo muhim hisoblanadi. Agar bizda faqatgina bir marta ishlatib keyinchalik kerak bo'lmaydigan kodlarimiz bo'lsa IIFE patternidan foydalanishimiz maqsadga muvofiq. Chunki faqat bir marta ishga tushiralidan kod yozadigan bo'lsak, uni biror joyga funsiya sifatida saqlab qo'yishimizdan ma'no qolmaydi.

IIFE-dan yana private va public o'zgaruvchi hamda metodlarni yaratishda ham foydalansa bo'ladi:

(() => {
  console.log(this);
})();

bu koddagi this kalit so'zi global `window`ni beradi.

IIFE qachon ishlatiladi?

IIFE-dan quyidagi hollarda eng ko'p ishlatiladi:

  • Global o'zgaruvchilarga alias berishda
  • Private o'zgaruvchi va funksiyalar yaratishda
  • Takrorlanish ichida asinxron funksiyalarni ishlatganda.

Global o'zgaruvchilarga alias berishda

Agar bir xildagi nom bilan o'z obyektini export qiluvchi 2ta kutubxonamiz bo'ladigan bo'lsa, ularning nomlari o'zaro conflict bermasligi uchun IIFE-dan foydalanishimiz mumkin. Misol uchun JQuery va Cash kutubxonalarining ikkalasi ham o'z obyektini $ belgisi bilan export qiladi.

Biz bu ikkala kutubxona conflict bermasligi uchun $ o'zgaruvchisi aynan qaysi kutubxonaga tegishli ekanligini belgilab olamiz. Aytaylik $ o'zgaruvchi JQuery-ga tegishli bo'lsin (Cash uchun boshqa global o'zgaruvchi tanlaymiz). Endi bu o'zgaruvchini IIFE funksiyaga argument qilib berib, uning qaysi kutubxona uchun tegishli ekanligini ko'rsatamiz:

(function($) {
  // funksiyamiz ichida ishlashi kerak bo'lgan kod
})(jQuery);


Private o'zgaruvchi va funksiyalar yaratishda

Shuningdek, IIFE-dan global sohada yoki boshqa biror funksiya ichida private o'zgaruvchi va funksiyalar yaratishda foydalanishimiz mumkin.

Global sohaga qo'shilgan funksiya va o'zgaruvchilarga sahifada mavjud barcha scriptlar murojaat qila oladi. Aytaylik JavaScript faylimizda generateMagicNumber() nomli 900dan 1000gacha bo'lgan sonlar orasidan tasodifiy sonni qaytaradigan funksiyamiz va favoriteNumber nomli o'zgaruvchimiz bor bo'lsin:

function generateMagicNumber() {
  return Math.floor(Math.random() * 100) + 900;
}

console.log("This is your magic number: " + generateMagicNumber());

var favoriteNumber = 5;
console.log("Twice your favorite number is " + favoriteNumber * 2);

Endi, agar biz yana boshqa biror JavaScript faylni sahifaga yuklaydigan bo'lsak, yuklayotgan faylimizdagi script-lar ham generateMagicNumber() va favoriteNumber ga murojaat qila oladi. Ushbu funksiya va o'zgaruvchimizga boshqa fayldan murojaat qilishni va ularni o'zgartirishni cheklashda IIFE-dan foydalanmiz:

(function () {
  function generateMagicNumber() {
    return Math.floor(Math.random() * 100) + 900;
  }

  console.log("This is your magic number: " + generateMagicNumber());

  var favoriteNumber = 5;
  console.log("Twice your favorite number is " + favoriteNumber * 2);
})();

Endi bizning funksiya va o'zgaruvchimizga faqat o'zi e'lon qilingan fayl ichidagina murojaat qilishimiz mumkin bo'ladi.

Takrorlanish ichida asinxron funksiyalarni ishlatganda

JavaScript-da callback-lar takrorlanish (loop) ichida g'alati ko'rinishda ishlaydi. Misol uchun, 1dan 5gacha sanaylikda, har sanoq orasiga 1 soniya vaqt qo'yib, log xabar chiqarib turaylik:

for (var i = 1; i <= 5; i++) {
  setTimeout(function () {
    console.log('I reached step ' + i);
  }, 1000 * i);
}

Bu kodni ishga tushirsak, quyidagicha natijani olamiz:

I reached step 6
I reached step 6
I reached step 6
I reached step 6
I reached step 6

Yuqoridagi kod bo'yicha bir biridan 1 soniya farq bilan oshib boruvchi sonlar bilan xabar chiqishini kutgan edik. Ammo natijada barchasida sanoq 6ga yetganini ko'rsatyapti. Xo'sh, nega bunday bo'ldi?

Javob esa quyidagicha: JavaScript asinxron ishlovchi kodga duch kelganida u asinxron kod ishi tugamagunicha callback-ni ishlatishni kechiktirib turadi. Yuqoridagi misolda, console.log() timeout ishlaganidan keyin ishga tushadi.

Shuningdek, bu yerda JavaScript callback-imiz uchun closure ham yaratgan. Closure-lar yordamida esa callback-imiz for takrorlanishi tugab bo'lgan bo'lsa ham, i o'zgaruvchiga murojaat qila oladi.

Shunday qilib, setTimeout() funksiyasi ichidagi kod ishlashi kechiktirilganligi sababli takrorlanish operatoridagi i qiymati 6ga yetib borgan paytda setTimeout() ichidagi kodlar ishga tushadi. Natija esa yuqorida ko'rganimizdek chiqadi.

Bu muammoni IIFE bilan bartaraf qilsak bo'ladi:

for (var i = 1; i <= 5; i++) {
  (function (step) {
    setTimeout(function() {
      console.log('I reached step ' + step);
    }, 1000 * i);
  })(i);
}

Bu yerda IIFE-ni qo'llash orqali callback funksiyamiz uchun yangi soha (scope) yaratamiz. IIFE step parametrini qabul qiladi. Har safar IIFE chaqirilganda, joriy argument sifatida unga i o'zgaruvchini beramiz. Shunday qilib, callback ishga tushish uchun tayyor bo'lgan paytda, uning closure-ida step-ning to'g'ri qiymati mavjud bo'ladi.

Kodni ishlatib ko'ramiz. Natija:

I reached step 1
I reached step 2
I reached step 3
I reached step 4
I reached step 5

dasturlash javascript iife pattern