2.12 IIFE

 

IIFE জাভাস্ক্রিপ্টের অন্যতম জনপ্রিয় একটি ডিজাইন প্যাটার্ন। এটি ইফি বলেই উচ্চারণ করে। IIFE জাভাস্ক্রিপ্ট কমিউনিটি দীর্ঘদিন ধরে ব্যবহার করে আসছে কিন্তু এর মিসলিডিং শব্দটি ছিল “সেলফ-এক্সিকিউটিং এনোনিমাস ফাংশন” যা পরবর্তীতে Ben Alman এটির একটি উপযুক্ত নাম দিয়েছেন “IIFE”। আজকে এটার সম্পর্কে বিস্তারিত লেখার চেষ্টা করবো।

IIFE কি?

IIFE – এর পূর্ণরুপ হচ্ছে Immediately Invoked Function Expression। IIFE হল একটি ফাংশন যা একটি এক্সপ্রেশন হিসাবে ডিক্লেয়ার এবং ডিক্লেয়ারেশনের পরপরই এক্সিকিউট করা হয়।

IIFE সিনট্যাক্সঃ

নিম্নলিখিত সিনট্যাক্স দেখায় কিভাবে IIFE ডিফাইন করতে হয়ঃ

(function () {
   // code goes here...
})();

 

আপনি arrow function ব্যবহার করেও IIFE ডিফাইন করতে পারবেন।

(() => {
   // code goes here...
})();

 

IIFE কেন?

যখন আপনি একটি ফাংশন ডিফাইন বা ডিক্লেয়ার করেন, জাভাস্ক্রিপ্ট ইঞ্জিন গ্লোবাল অবজেক্টের সাথে ফাংশনকে যোগ করে। একইভাবে, যদি আপনি ফাংশনের বাইরে একটি ভেরিয়েবল ডিক্লেয়ার করেন, জাভাস্ক্রিপ্ট ইঞ্জিন ঐ ভেরিয়েবলকে গ্লোবাল অবজেক্টের সাথে যোগ করে। নিম্নলিখিত উদাহরণ দেখুনঃ

var num = 7;

function sum(a, b) {
   return a + b;
}

console.log(window.sum); /**
ƒ sum(a,b) {
   return a + b;
}
*/
console.log(window.num); // 7

 

যদি আপনার প্রোগ্রামে অনেক গ্লোবাল ভেরিয়েবল এবং ফাংশন থাকে, তাহলে আপনার প্রোগ্রাম ইনইফিশিয়েন্টলি মেমোরি ব্যবহার করতে পারে এবং আপনার গ্লোবাল ভেরিয়েবল এবং ফাংশনগুলি অন্য কোন লাইব্রেরীর সাথে কনফ্লিক্ট করতে পারে যদি ঐ লাইব্রেরীতে একই নামে ভেরিয়েবল এবং ফাংশন থাকে। ফাংশন এবং ভেরিয়েবলগুলিকে গ্লোবাল অবজেক্ট কনফ্লিক্ট করা থেকে বিরত রাখার একটি উপায় হল IIFE ব্যবহার করা।

নেইমড IIFE:

(function domeSomeMagic() {
   // code goes here...
})();

 

IIFE সেমিকোলন দিয়েও শুরু হতে পারে। যেমন:

(function () {
   // code goes here...
})();

 

এই সিনট্যাক্সে, দুই বা ততোধিক জাভাস্ক্রিপ্ট ফাইলকে একক ফাইলে বান্ডল করার জন্যে স্টেটমেন্টটি শেষ করতে সেমিকোলন ব্যবহার করা হয়। উদাহরণস্বরূপ, আপনার দুটি ফাইল আছে file1.js এবং file2.js যা IIFE ব্যবহার করে।

/**
 * file1.js
 */

(function () {
  // ...
})();

 

/**
* file2.js
*/

(function () {
   // ...
})();

 

যদি আপনি একটি কোড বান্ডলার টুল ব্যবহার করে উভয় ফাইলগুলির কোডকে একটি একক ফাইলের কোড কনকেট করতে চান সেমিকোলন (;) ছাড়া, কনকানেটেড কোডটি একটি Uncaught TypeError: (intermediate value)(…) is not a function সিনট্যাক্স ইরের দিবে।

ধরুন আপনার নিম্নলিখিত ফাংশন সহ math.js নামে একটি লাইব্রেরি আছে এবং একটি HTML ফাইলে math.js লোড করুনঃ

function add(a, b) {
   return a + b;
}

function sub(a, b) {
   return a - b;
}

function mult(a, b) {
   return a * b;
}

function div(a, b) {
   return a / b;
}

 

পরবর্তীতে, আপনি একই ফাইলে anotherLibraby.js নামে আরেকটি জাভাস্ক্রিপ্ট লাইব্রেরি লোড করতে চানঃ

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>JavaScript IIFE</title>
  </head>
  <body>
    <script src="math.js"></script>
    <script src="anotherLibrary.js"></script>
    <script src="app.js"></script>
  </body>
</html>

 

anotherLibrary.js লাইব্রেরীতেও sub() নামে ফাংশন রয়েছে যেটি একটি স্ট্রিং রিটার্ন করেঃ

function sub() {
  return "sub";
}

যখন আপনি app.js ফাইলে sub() ফাংশনটি ব্যবহার করবেন, তখন এটি দুটি সংখ্যার বিয়োগের পরিবর্তে sub স্ট্রিং রিটার্ন করবেঃ

let result = sub(30, 20);
console.log(result);        // sub

কারণ anotherLibrary.js এর sub() ফাংশন math.js লাইব্রেরির sub() ফাংশনকে ওভাররাইড করে ফেলছে।

এই সমস্যা ঠিক করতে, আপনি math.js এ IIFE ব্যবহার করতে পারেনঃ

var math = (function () {
   function add(a, b) {
     return a + b;
   }

   function sub(a, b) {
     return a - b;
   }

   function mult(a, b) {
     return a * b;
   }

   function div(a, b) {
     return a / b;
   }

   return {
     add: add,
     sub: sub,
     mult: mult,
     div: div,
   };
})();

 

IIFE math নামে একটি অবজেক্ট রিটার্ন করে যাতে add, sub, mult, এবং div মেথড হয়েছে।

app.js ফাইলে, আপনি math.js লাইব্রেরি নিম্নলিখিতভাবে ব্যবহার করতে পারেনঃ

var result = math.sub(30, 20);
console.log(result);       // 10
console.log(sub());       // sub

 

প্রথম sub() ফাংশনকে math.sub() দিয়ে ইনভোক করা হয়েছে যেটি math.js থেকে এক্সপোর্ট করা অন্যদিকে দ্বিতীয় sub() ফাংশনকে anotherLibrary.js থেকে ইনভোক করা হয়েছে।

 

IIFE এর সুবিধাঃ

  • অপ্রয়োজনীয় গ্লোবাল ভেরিয়েবল এবং ফাংশন তৈরি করে না।
  • IIFE তে ডিফাইন করা ফাংশন ও ভেরিয়েবল অন্য ফাংশন এবং ভেরিয়েবলের সাথে কনফ্লিক্ট করে না। এমনকি তাদের একই নাম থাকলেও।
  • জাভাস্ক্রিপ্টের কোড অর্গানাইজ করে।
  • জাভাস্ক্রিপ্ট কোড মেইন্টানাবল করে।
 
উদাহরন
  • Normally, IIFE does not require a name. But even when we name an IIFE, it keeps on working.
(function greetings() {
  let message = "Hello, I am Sam Smith";
  console.log(message);
}());
  • Execute an async function
const getFileStream = async (url) => { 
  /* implementation */
};

(async () => {
  const stream = await getFileStream('https://www.vivasoftltd.com/file.ext');
  for await (const chunk of stream) {
    console.log({ chunk });
  }
})();
  • IIFE that Takes Arguments
    (function (first, last) {
      alert(`My name is ${first} ${last}.`);
    })("Lukman", "Hussain");
    

     

এসো নিজে করি
  • Use an IIFE to immediately execute the calculate function.
function calculate(){
  let a = 12;
  let b = 34;
  console.log(a + b);
}
  • Writing an IIFE that Takes 3 Arguments and return sum.
  • Write and IFFE that return an object.