জাভাস্ক্রিপ্টঃ ক্লোজারস(Closures) নিয়ে ধারণা

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

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

আগেই যেহেতু বলেছি এটাও জাভাস্ক্রিপ্ট এর ডিফল্ট বিহেভিয়ার। অর্থাৎ আমাদের ক্লোজারস আলাদা করে কোড করতে হবে না।

এখন কিভাবে এই ক্লোজারস কাজ করে। আমরা জানি জাভাস্ক্রিপ্ট এ আপনি চাইলে ফাংশন থেকেও আরেকটা ফাংশন রিটার্ন করতে পারবেন। আর তখনি তৈরী হয় প্যারেন্ট-চাইল্ড রিলেশন। আর রিটার্নকৃত ফাংশনের সবকিছু চাইল্ড ফাংশন চাইলেও অ্যাক্সেস করতে পারে ক্লোজারস এর কারণে।

function closuresDemo() {
   var x = 10;
   return function() {
      var y = 20;
      console.log('Sum: ' + (x + y));
   }
}

এখন এই ফাংশনকে কল করলে দেখবেন নিচের চাইল্ড ফাংশন প্যারেন্ট ফাংশনের ভ্যারিয়েবল x এর অ্যাক্সেস পাচ্ছে যদিও প্যারেন্ট ফাংশনটা রিটার্ন হয়ে গেছে।

closuresDemo()();

এখানে ভিতরের চাইল্ড ফাংশনটা অ্যানিনোমাস ফাংশন যেহেতু এটাকে রিটার্ন করা হচ্ছে সরাসরি, আপনি চাইলে চাইল্ড ফাংশনটাকেও একটা নাম দিতে পারেন তবে কাজে লাগবে না এক্ষেত্রে। আর তাই closuresDemo এর প্রথম কলে প্রথম প্যারেন্ট ফাংশন এক্সিকিউট হবে এবং আরেকটা কলে চাইল্ড ফাংশন এক্সিকিউট হবে। তাই এখানে দুইটা ব্র্যাকেটস ()() লেগেছে।

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

var aVar = closuresDemo();
var total = aVar();
console.log(total);

এটাও ঠিক আগেরমতোই রেজাল্ট শো করবে। জাস্ট দেখানোর জন্যে চাইলে এভাবেও কাজ করা যায়। কোনটা ইউজ করবেন সেটা সম্পূর্ন আপনার উপর।

এভাবে চাইলে আমরা আর্গুমেন্টস পাস করেও সেগুলা প্যারেন্টস থেকে চাইল্ড এ শেয়ার করতে পারবো। মানে প্যারেন্টস এর আর্গুমেন্টসগুলোও চাইল্ড অ্যাক্সেস করতে পারবে।

function aParentFunc(a) {
   return function(b) {
      console.log('Sum: ' + (a + b));
   }
}

এখন এই ফাংশনটাকে আর্গুমেন্টসহ পাস করে কল করলে দেখবেন এটা প্যারেন্ট থেকে নেওয়া a এবং চাইল্ডের b একসাথে যোগ করে সেটার সাম দেখাচ্ছেঃ

aParentFunc(6)(4);

এখানে প্যারেন্ট এর আর্গুমেন্ট প্যারেন্ট ফাংশন কল করার সময় সেটার ব্র্যাকেটস এর ভিতরে যাবে এবং চাইল্ডেরটা চাইল্ডের কলের সময়কার ব্র্যাকেটসের ভিতরে যাবে।

এভাবে ডাবল ব্র্যাকেটস ইউজ না করে প্রথমে প্যারেন্ট ফাংশনটাকে কল করে একটা ভ্যারিয়েবলে রেখে পরে আবার সেই ভ্যারিয়েবলের সাহায্যেও চাইল্ড ফাংশনটাকে কল করতে পারবেন

var aParentVar = aParentFunc(6);
var total = aParentVar(4);

এটাও ঠিক আগের মতোই ফলাফল দেখাবে। কিন্তু লক্ষ্য করুন যার যার আর্গুমেন্ট তার তার কলেই পাস করা হয়েছে

আশা করি ক্লোজারস নিয়ে আর কোনো কনফিউশান থাকবে না আজকে থেকে। ব্যাসিক আইডিয়াটা রাখতে পারলে পরে যেকোনো সিচুয়েশানেই আপনি ক্লোজারস নিয়ে কাজ করতে পারবেন।

তো আজকে এই পর্যন্তই, ভালো থাকবেন আর পাশের মানুষটিকে ভালো রাখবেন।

শেয়ার করুন

লেখাটি ভাল লাগলে সোশ্যাল মিডিয়ায় শেয়ার করুন। আপনার কলিগ, বন্ধু কিংবা প্রিয় কারও কাজে লাগতে পারে। জানেন তো, শেয়ারিং ইজ কেয়ারিং!

সাবস্ক্রিপশন সেন্টার

প্রতিদিন ওয়েবসাইটে আসা আপনার জন্য কষ্টকর হতে পারে। তাই যখনই আমি নতুন ব্লগ পোস্ট, সিরিজ, বই বা ভিডিও পাবলিশ করব,
তখনই তা আপনার ইমেইলে পেতে সাবস্ক্রাইব করুন। নো স্প্যামিং প্রমিজ!