জাভাস্ক্রিপ্ট ডেভদের জন্যে একটা আতঙ্কের নাম হচ্ছে closure। এই closure সম্পর্কে পরিষ্কার ধারণা না থাকার কারণে অনেক সময় জব ইন্টার্ভিউতেও পর্যন্ত বেশ ভাল নাকানি-চোবানি খেতে হয়। আমাদের আজকের আলোচ্য বিষয় হচ্ছে closure নিয়ে। তাহলে চলুন শুরু করা যাক এর গোষ্ঠী উদ্ধারের মিশন।

ক্লোজার কি?

Closure কোন ফাংশন না আবার ফাংশনও কোন closure না। Closure হচ্ছে ফাংশনের এমন একটা বৈশিষ্ট্য যে বৈশিষ্ট্যের কারণে ফাংশন এক্সিকিউশন শেষ হয়ে যাবার পরেও তার lexical scope এ অবস্থিত সকল variable কে মনে রাখতে পারে। উদাহরণস্বরূপ বলা যেতে পারে যে ডম থেকে কিছু অ্যাক্সেস করার জন্যে আমরা যে ইভেন্ট ফাইয়ার করি সেটাও একটা closure।

কিছু উদাহরণঃ
function add(a) {
return function(b) {
return a + b;
};
}

let addTen = add(10);
let addSeven = addTen(7);

console.log(addSeven); // 17

 

কি হচ্ছে এসব?? ঠিক আছে, চলেন দেখি কোডগুলোকে ভেঙ্গেঃ-

১। যখন add ফাংশনটি কল হয় এটি আরেকটি ফাংশনকে return করে।
২। ঐ ফাংশনটির এক্সিকিউশন শেষ হয়ে যায় এবং মনে রাখে ঐ সময় তার প্যারামিটার a এর ভ্যালু কি ছিল।
৩। যখন addTen ভেরিয়েবলে add ফাংশনকে এসাইন করা হয়। এটি সব সময় মনে রাখবে a এর ভেল্যু কি ছিল যখন এটিকে ইনিশিয়ালি কল করা হয়েছিল।
৪। উপরের addTen ভেরিয়েবল একটি ফাংশনকে বোঝায় যেটি সব সময় ভেল্যু ১০ যোগ করবে যা পাঠানো হয়েছিল।
৫। তার মানে হল যখন addTen কে কল করা হয় ৭ ভেল্যু দিয়ে, এটি ১০ এর সাথে ৭ যোগ করবে এবং ১৭ রিটার্ন করবে।

**সুতারং, জাভাস্ক্রিপ্ট ইঞ্জিন addTen কে যেভাবে রান করেঃ-**

function addTen(b) {
return 10 + b;
}

এখন একটা মজার উদাহরণ দেখবো। কিভাবে আমরা লুপের ভিতরে ক্লোজার চালাতে পারি। এটি ইন্টার্ভিউ বোর্ডের একটা কমন প্রশ্ন। নিচের কোডটা দেখেন এবং একটু মনে মনে চিন্তা করেন এটার আউটপুট কত হবে।

for(var i = 1; i <= 5; i++) { setTimeout(() => console.log(i), 1000);
}

 

কাঙ্ক্ষিত আউটপুটঃ-
1
2
3
4
5
কিন্তু আসছে অনাকাঙ্ক্ষিত আওউটপুটঃ-
6
6
6
6
6

আসলে এই আউটপুট আসার অনেক কারণ আছে। লুপের মাঝে ভ্যারিয়াবল i হচ্ছে একটি গ্লোবাল ভ্যারিয়াবল। যখন setTimeout রান হয় তার আগেই লুপ শেষ হয়ে যায় এবং তাই i ভ্যালু 6 হয়ে যায়। সেজন্যে প্রতি এক সেকন্ড পর পর পাঁচবার 6 দেখাচ্ছে। যদি বিশ্বাস না হয় তাহলে কোডটা রান করার পর আপনার গ্লোবাল window অবজেক্টটা একবার দেখেন সেখানে i নামে একটা ভ্যারিয়াবল দেখতে পারবেন এবং তার ভ্যালু 6 হয়ে আছে।

এই সমস্যার সমাধান আমরা IIFE বা Immediately Invoked Function Expression ব্যবহার করে করতে পারি। নিচে উদাহরণ দেওয়া হলঃ-

পদ্ধতি ১ঃ-
for(var i = 1; i <= 5; i++) { (function() { var val = i; setTimeout(() => console.log(val), 1000);
}());
}
পদ্ধতি ২ঃ-
for(var i = 1; i <= 5; i++) { (function(val) { setTimeout(() => console.log(val), 1000);
}(i));

 

এখানে আমরা একটা ফাংশন লিখে একটা Scope তৈরি করেছি। ফাংশনটিকে ইমিডিয়েটলি কল করেছি এবং তার প্যারামিটারের ভেল্যু হিসাবে i কে পাস করেছি। এতে সে এখন i এর ভেল্যুকে মনে না রেখে সে এখন তার প্যারামিটারের ভেল্যুকে মনে রাখবে। মানে এখন i এর মান 1, 2 করে যাচ্ছে এবং সেটা থেকে একটা আলাদা Scope তৈরি হচ্ছে যেটাকে সে মনে রাখছে।

আউটপুটঃ-
1
2
3
4
5

অবশেষে আমাদের কাঙ্ক্ষিত আউটপুট ফেলাম। তবে আজ এই পর্যন্ত দেখা পরবর্তী অন্য টপিকে। হ্যাপি কোডিং…

**বিঃ দ্রঃ** [এখানে ক্লিক](https://shahansdiary.com/what-is-closure-in-javascript/) করে লেখকের ব্যক্তিগত ব্লগেও পড়তে পারবেন