JS 101: জাভাস্ক্রিপ্ট প্রোগ্রামিংয়ে ক্লোজার যেভাবে কাজ করে।

--

Photo by Sterling Davis on Unsplash

Closure is when a function is able to access variables from an outer function that has already returned.

আলোচনার বিষয়বস্তুঃ

ক্লোজার কি
ক্লোজার কিভাবে কাজ করে
সারমর্ম
রিসোর্স সমূহ

ক্লোজার কিঃ

ক্লোজার জাভাস্ক্রিপ্টের এমন গুরুত্বপূর্ণ একটি বিষয় যা না জনলে আপনার জাভাস্ক্রিপ্ট কোডের আচরণ হবে অনেকটা গ্রামার না জেনে ইংরেজি বলার মত। আপনি হইতো কথা বলতে পারবেন কিন্তু সঠিক ভাবে যা বুঝাতে চাচ্ছেন তা বুঝাতে পারবেন না। তো চলুন জেনে নেই কি এই ক্লোজার —

আসলে ক্লোজার বুঝার আগে জাভাস্ক্রিপ্টের লেক্সিক্যাল স্কোপ বুঝতে হবে। জাভাস্ক্রিপ্টে স্কোপ দুই প্রকার —

১। গ্লোবাল স্কোপ

২। লোকাল স্কোপ

গ্লোবাল স্কোপঃ — যদি আপনার কোন একটি ভেরিয়েবল আপনার প্রোজেক্টের সব জায়গা থেকে অ্যাক্সেস করা যায় তবে সেটা গ্লোবাল স্কোপে আছে।

var globalName = 'Md. Abdur Rouf';function globalFunction() {
return globalName;
}
console.log(globalFunction()); // Md. Abdur Rouf
console.log(globalName); // Md. Abdur Rouf

উপরের কোডে দেখা যাচ্ছে একটি গ্লোবাল ভেরিয়েবল globalName ডিক্লেয়ার করা হয়েছে। যা globalFunction() এর ভিতরেও অ্যাক্সেস করা যায় আবার শুধু শুধু globalName ভেরিয়েবল কল করেও অ্যাক্সেস করা যায়। এইটাই হচ্ছে গ্লোবাল স্কোপ

মানে কোন একটা ভেরিয়েবল, ফাংশন বা অবজেক্টকে গ্লোবালি ডিক্লেয়ার করে বিভিন্ন জায়গা থেকে অ্যাক্সেস করতে পারা।

লোকাল স্কোপঃ — যদি কোন একটা ভেরিয়েবল নির্দিষ্ট একটি ফাংশনের ভিতরে শুধু মাত্র কাজ করে এবং ওই ফাংশনের বাইরে কাজ না করে তবে সেটি লোকাল ভেরিয়েবল এবং এই স্কোপকে বলে লোকাল স্কোপ

function localFunction() {
let localName = 'Md. Jamal Uddin';

return localName;
}
console.log(localFunction()); // Md. Jamal Uddin
console.log(localName); // ReferenceError: localName is not defined

এবার দেখুন localFunction এর ভিতরে localName ভেরিয়েবল টি ঠিক মত কাজ করলেও localFunction এর বাইরে কিন্তু localName ভেরিয়েবল টি কাজ করছে না।

চলুন এখন আমরা ক্লোজার এর দিকে এগিয়ে যায় —

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives you access to an outer function’s scope from an inner function. In JavaScript, closures are created every time a function is created, at function creation time. — Eric Elliott

ক্লোজার হচ্ছে, যখন কোন ফাংশন এর লেক্সিকাল স্কোপ এর বাইরে এক্সিকিউট হওয়া সত্ত্বেও ঐ লেক্সিকাল স্কোপ কে মনে রাখতে এবং ব্যবহার করতে পারে।

মানে ঘটনা এমন যে — প্রথমে একটি ফাংশন ডিক্লেয়ার করলাম। তার ভিতরে আরেকটা অ্যানোনিমাস ফাংশন ডিক্লেয়ার করলাম। এবার প্রথম ফাংশন টা রিটার্ন করে দিলাম। মজার ব্যাপার এখনো আমি অ্যানোনিমাস ফাংশন টা ব্যবহার করতে পারবো। যেখানে আগের ফাংশনের ভেরিয়েবল সমুহ অ্যাক্সেস করা যায়।

আমার কথা মনে হয় কিছুই বুঝলেন না। চলেন কোড করে দেখি -

function outer() {  
var name = 'Muslim';

return function() {
return 'Hello ' + name;
}
}
var sayHi = outer();
console.log(name); // Reference Error
cosnole.log(sayHi()); // Hello Muslim

এখানে outer একটি কমন ফাংশন যেখানে name নামের একটি লোকাল ভেরিয়েবল আছে। নরমালি কোন লোকাল ভেরিয়েবল কে তার স্কোপ এর বাইরে কল করে পাওয়ার কথা না। কিন্তু ক্লোজারের কারণে এখানে sayHi() ফাংশনের ভ্যালু হিসেবে name এর ভ্যালু প্রদর্শিত হচ্ছে।

আসল ঘটনা হচ্ছে যে, ক্লোজার এর মাধ্যমে অন্নের ঘরে আপনি অ্যাক্সেস পেয়ে যাচ্ছেন।

আরও একটি উদাহরণ দেখি -

const add = ( a ) => ( b ) => a + b;let addTen = add(10);
let addTweenty = add(20);
console.log(addTen(2)); // 12
console.log(addTweenty(3)); // 23

ক্লোজার কিভাবে কাজ করেঃ

যখন জাভাস্ক্রিপ্ট কোন ফাংশন execute করে, ঐ ফাংশনের লোকাল ভ্যারিয়েবল গুলো রাখার জন্যে একটি ‘স্কোপ’ অবজেক্ট তৈরি করা হয়। এই স্কোপ ভ্যারিয়েবল ইনিশিয়ালাইজ করা হয় ফাংশনে প্যারামিটার হিসেবে যেসব ভ্যারিয়েবল পাঠানো হয়েছিল সেগুলো দ্বারা। এটা গ্লোবাল অবজেক্টের মতই যেখানে সব গ্লোবাল ভ্যারিয়েবল আর ফাংশনগুলো থাকে, কিন্তু দু’টির মধ্যে পার্থক্য বিদ্যমান।

প্রথমতঃ প্রতিবার একটি ফাংশন execute হওয়া শুরু করে একটি নতুন স্কোপ অবজেক্ট তৈরি হয়ে যায়।

দ্বিতীয়তঃ গ্লোবাল স্কোপের প্রোপার্টি সরাসরি এক্সেস করা যায় (যেমন ব্রাউজারের ক্ষেত্রে এই গ্লোবাল অবজেক্ট টি হল window), কিন্তু ফাংশনের স্কোপের ক্ষেত্রে এটি সম্ভব নয়। উদাহরণস্বরূপ বলা যায়, ফাংশনের স্কোপ অবজেক্টের প্রোপার্টিকে iterate করে এক্সেস করা সম্ভব নয়।

তাই যখন add কল করা হয়েছে, তখন একটা স্কোপ অবজেক্ট তৈরি হয়ে গেছে। এই স্কোপ অবজেক্টের একটাই প্রোপার্টিঃ a ভ্যারিয়েবল যেটি কিনা এই ফাংশনের একমাত্র প্যারামিটার। add তারপর নতুন একটা ফাংশন তৈরি করে রিটার্ন করে। এই মুহূর্তে জাভাস্ক্রিপ্টের গারবেজ কালেকটর সাহেব add এর স্কোপ অবজেক্ট গায়েব করে ফেলার কথা, কিন্তু add যে ফাংশনটি তৈরি করে রিটার্ন করল তার মাঝে add এর স্কোপ অবজেক্টের একটা রেফারেন্স থেকে যায়। যে কারণে, যতক্ষণ add এর রিটার্ন করা ফাংশনের কোন না কোন রেফারেন্স কোডে অবশিষ্ট থাকছে (সহজভাবে যতক্ষণ এটি ব্যবহৃত হচ্ছে), ততক্ষণ add এর স্কোপ অবজেক্ট-টিও অক্ষত থাকবে।

স্কোপ অবজেক্টরা প্রোটোটাইপ চেইনের মত স্কোপ চেইন মেইনটেইন করে।

তাই বলা যায় -

ক্লোজার হচ্ছে, একটি ফাংশন আর এই ফাংশনকে যেই ফাংশন তৈরি করেছিল তার স্কোপ অবজেক্টের একটা সমন্বয় (combination)।

ক্লোজার আপনাকে স্টেট মনে রাখার একটা সুবিধা দেয় — যে কারণে অবজেক্টের বদলে ক্লোজার ব্যবহার করা যেতে পারে।

সারমর্মঃ

  • Closure exists when an inner function makes use of variables declared in an outer function which has previously returned
  • যখন একটি inner ফাংশন তার outer ফাংশনে ডিক্লেয়ার করা কোন ভেরিয়েবল কে ব্যবহার করে মান রিটার্ন করে তখন সেটি একটি ক্লোজার। এক্ষেত্রে outer ফাংশন টি আগেই রিটার্ন হয়ে থাকে।
  • Closure does not exist if you do not return an inner function and if that inner function does not make use of variables returned by an outer function
  • যদি কোন ফাংশনের মধ্যে আরও একটি ফাংশন রিটার্ন করা না হয় তবে তা ক্লোজার হিসেবে বিবেচিত হবে না। এবং অবশ্যই inner ফাংশনে outer ফাংশনের কোন ভেরিইয়েবল বাবহ্রিত হতে হবে। তাছাড়া নেসটেড ফাংশন হিসেবে বিবেচিত হবে।
  • We can use closures to create private variables and write better code that isolates our logic and application
  • আমরা ক্লোজার ব্যবহার করে প্রাইভেট ভেরিয়েবল ডিক্লেয়ার করতে পারি। এছাড়া কোড কে সুন্দর ও অরগানিজ করার জন্য ক্লোজার ব্যবহার করা যায়। ক্লোজার জাভাস্ক্রিপ্ট কোডে Abstraction এর সুবিধা প্রদান করে। আমাদের আপ্লিকেশনের লজিক সমুহ খুব সুন্দর ভাবে একে অপরের সাথে আইসোলেট করতে পারি ক্লোজার ব্যবহার করে।

প্রেমিক কুদ্দুসের ক্লোজার’ময় প্রেমের গল্প পড়তে নিচের লিঙ্কে ক্লিক করুন —

আরো জানতে দেখুন এই রিসোর্স সমূহঃ

১। https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

২। https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36

৩। https://javascript.info/closure

৪। https://www.geeksforgeeks.org/closure-in-javascript/

আমার সম্পর্কেঃ

আমি মোঃ জামাল উদ্দিন, প্রতিনিয়ত শিখছি এবং যা কিছু শিখছি তা আপনাদের সাথে লেখালেখির মাধ্যমে শেয়ার করার চেষ্টা করছি। কাজ করছি সফটওয়্যার ডেভেলপার হিসেবে। আমার সম্পর্কে বিস্তারিত জানতে ভিজিট করুন https://jaamaalxyz.github.io ওয়েবসাইটে এবং প্রায় সবগুলো জনপ্রিয় সোশ্যাল সাইটে আমাকে পাবেন jaamaalxyz ইউজারনামে।

--

--

Md. Jamal Uddin
প্রোগ্রামিং পাতা

Software engineer passionate about building and delivering SaaS apps using React Native. Agile enthusiast who occasionally writes blog posts about life and tech