Posts

জাভাস্ক্রিপ্টে কলব্যাক ও হাইয়ার অর্ডার ফাংশন

কলব্যাক ব্যাপারটি আমাদের জীবনের সাথে ব্যাপকভাবে জড়িয়ে আছে। যদি “সে” কলব্যাক না করে আপনি হয়তো “অ” হয়ে যান! ইয়ে মানে বলতে চাচ্ছিলাম যে অভিমানী নয়তো অস্থির হয়ে যান 😉 আর যদি আপনার লাইফে “সে” না থাকে তবে তো কোন কথাই নেই। আমার মত বিন্দাস 😂। যাইহোক, আপনি “অ” হোন আর না হোন, “সে” কলব্যাক করুক আর না করুক আজকে আমরা কলব্যাক নিয়ে আলোচনা করবই। চলুন তাহলে শুরু থেকেই শুরু করি…

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

কলব্যাক ফাংশন কি?

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

হাইয়ার অর্ডার ফাংশন কি?

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

আমাদের এমন একটি ফাংশন আছে যেটি আর্গুমেন্ট হিশাবে একটি অ্যারে নিবে এবং সেটি কে মডিফাই করে একটি নতুন অ্যারে নিটার্ন করবে। এক্ষেত্রে, আমাদের ফাংশনটিকে যে অ্যারে দেওয়া হবে তার সাথে দুই যোগ করে নতুন একটি অ্যারে নিটার্ন করবে।

function modifyBy2(arr) {
    let output = [];

    for(let i = 0; i < arr.length; i++) {
        output.push(arr[i] + 2);
    }

    return output;
}

const newArr = modifyBy2([1,2,3,4,5,6]);
console.log(newArr); // [3, 4, 5, 6, 7, 8]

এখন আমাদের আরেকটি ফাংশন আছে যেটি আর্গুমেন্ট হিশাবে একটি অ্যারে নিবে এবং যে অ্যারে দেওয়া হবে তার সাথে দুই গুণ করে নতুন একটি অ্যারে নিটার্ন করবে।

function multifyBy2(arr) {
    let output = [];

    for(let i = 0; i < arr.length; i++) {
        output.push(arr[i] * 2);
    }

    return output;
}

const newArr = modifyBy2([1,2,3,4,5,6]);
console.log(newArr); // [2, 4, 6, 8, 10, 12]

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

function modifyArray(arr, fn) {
    let output = [];

    for(let i = 0; i < arr.length; i++) {
        output.push(fn(arr[i]));
    }

    return output;
}

function modifyBy2(elem) {
    return elem + 2;
}

const newArr = modifyArray([1,2,3,4,5,6], modifyBy2);
console.log(newArr); // [3, 4, 5, 6, 7, 8]

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

function modifyArray(arr, callback) {
    let output = [];

    for(let i = 0; i < arr.length; i++) {
        output.push(callback(arr[i]));
    }

    return output;
}

function addBy2(elem) {
    return elem + 2;
}

function multifyBy2(elem) {
    return elem * 2;
}

const additionArr = modifyArray([1,2,3,4,5,6], addBy2);
const multiArr = modifyArray([1,2,3,4,5,6], multifyBy2);

console.log(additionArr); // [3, 4, 5, 6, 7, 8]
console.log(multiArr); // [2, 4, 6, 8, 10, 12]

modifyArray ফাংশনটিতে আর্গুমেন্ট হিসাবে যে ফাংশনটিকে পাস করতেছি ওই ফাংশনটিই হচ্ছে একটি কলব্যাক ফাংশন এবং modifyArray ফানশনটি হচ্ছে একটি হাইয়ার অর্ডার ফাংশন

বিঃ দ্রঃ এই হচ্ছে কলব্যাক এবং ঊচ্চমার্গীয় ফাংশনের কাজ কারবার। এইবার কি কলব্যাক এবং ঊচ্চমার্গীয় ফাংশন মাথার নিচ দিয়ে যাচ্ছে?? এরপরও যদি ৬০০+ ওয়র্ডের একটা লেখা পড়ে মাথার উপর দিয়ে যায় তাহলে কমেন্ট বক্সে কমেন্ট করে উড়াই দিবেন, আমি ধরে নিবো।

এখানে ক্লিক করে লেখকের ব্যক্তিগত ব্লগেও পড়তে পারবেন

জাভাস্ক্রিপ্টে স্কোপ কি?

জাভাস্ক্রিপ্টের আলোচিত বিষয়গুলোর মাঝে একটি হল Scope। আপনি যদি একজন নতুন জাভাস্ক্রিপ্ট প্রোগ্রামার হয়ে থাকেন তাহলে এটির সাথে ভাল করে পরিচয় হওয়া অতি প্রয়োজন। তাই আজকে scope নিয়ে মনের কিছু কথা বলতে চাচ্ছি। 😛

Scope কি?

Scope মূলত একটা নির্দিষ্ট সীমানাকে বোঝায়। যার বাহিরে Variable এবং Function-গুলো এক্সেসিবল না। যদি এই সীমানার বাহিরে কোন Variable এবং Function কে কল করা হয় তাহলে তার কোন অস্তিত্ব থাকবে না। একটি কথা ভাল করে মাথায় সংরক্ষণ করে রাখেন যে, জাভাস্ক্রিপ্টে একমাত্র তখনই Scope তৈরি হয়, যখন আমরা কোন function ইনভোক বা কাল করি। হ্যাঁ, function ছাড়া আর কোথাও Scope তৈরি হয় না। আর এই Scope হচ্ছে দুই প্রকার- ১. Global Scope এবং ২. Local Scope

১. Global Scope

জাভাস্ক্রিপ্টে বাই ডিফল্ট সব কিছু Global Scope – এ রান হয়ে। যার এক্সেসিবল সব জায়গায় থাকে। উদাহরণস্বরূপ-

var globalVariable = "I am global variable.";
console.log(globalVariable); // I am global variable.

var myFunc = function() {
    console.log(globalVariable);
}

myFunc() // I am global variable.

উপরের কোডটুকু রান করলে দেখতে পারবেন যে globalVariable নামের ভেরিয়েবলটিকে সব যায়গায় ব্যবহার করা যাচ্ছে এবং সবার আউটপুটও একই দেখাচ্ছে।

২. Local Scope

আগেই বলেছিলাম যে, জাভাস্ক্রিপ্ট একমাত্র Scope তৈরি করে কোন Function ইনভোক বা কাল করলে। এই Scope কেই বলা হয় Local Scope। মানে হচ্ছে, তার ভিতরে যা কিছু থাকবে তার নিজস্ব Scope – এর বাহিরে এর কোন অস্তিত্ব থাকবে না। অর্থাৎ, তার Scope – এর ভিতরে লিখা কোন ভেরিয়েবলকে যদি আমরা বাহিরে অন্য কোথাও ব্যবহার করতে চাই তাহলে জাভাস্ক্রিপ্ট খুব সুন্দর করে একটি আনকট রেফারেন্সে ইরর দিয়ে বলে দিবে যে খোকা তুমি যাকে ব্যবহার করতে চাচ্ছ সে তো কোথাও ডেফাইন করা নেই। চলুন একটা উদাহরণ দিয়ে দেখা যাক-

var globalVariable = "I am global variable.";

var myFunc = function() {
    var localVariable = "I am local variable.";

    console.log(globalVariable);
    console.log(localVariable);
}

myFunc();
// I am global variable.
// I am local variable.

console.log(localVariable); // udefined

উপরের কোডটুকু রান করলে দেখতে পারবেন যে প্রথমে দেখাচ্ছে I am global variable. এবং I am local variable. তারপর অতি ভদ্রতার সাথে খুব সুন্দর করে বলে দিছে যে আনকট রেফারেন্সেঃ লোকাল ইজ নট ডিফাইন্ড।

Lexical Scoping কি?

এখন সবার মনে প্রশ্ন আসতে পারে যে, এই Lexical Scoping – টা আবার কি? একটু অপেক্ষা করেন মাথা গরম করার কোন দরকার নেই। আসলে জাভাস্ক্রিপ্টকে বলা হয় Lexical Scoping ল্যাঙ্গুয়েজ। আমরা ফাংশনের ভিতরে আমাদের প্রয়োজন অনুযায়ী একাধিক ফাংশন তৈরি করতে পারি এবং চাইল্ড ফাংশনগুলো তার প্যারেন্ট ফাংশনের সব ভেরিয়াবলস এবং আর্গুমেন্টেসের এক্সেস পায়। কিন্তু আউটার ফাংশনগুলো তার চাইল্ড ফাংশনের ভেরিয়াবলস এবং আর্গুমেন্টেসের কোন এক্সেস পায় না। এই যে চাইল্ড ফাংশনগুলো তার প্যারেন্ট ফাংশনের ভেরিয়াবলস এবং আর্গুমেন্টেসের এক্সেস পাচ্ছে এই এক্সেস পাওয়াকেই বল হয় Lexical Scoping

function outerFunc(a) {
     var outerFuncVariable = "Hi there, I am outer " + a;

     console.log(outerFuncVariable); // Hi there, I am inner function variable

     function innerFunc() {
         var innerFuncVariable = "Hi there, I am inner " + a;
         console.log(innerFuncVariable);
     }

     innerFunc(); // Hi there, I am inner function variable

     console.log(innerFuncVariable); // undefined
 }

 outerFunc("function variable");

নোটসঃ

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

আশা করি, এখন Scope কি এবং Lexical Scoping কি কিছুটা হলেও বুঝতে পারছেন। আজ এই পর্যন্তই পরবর্তীতে অন্য কোন টপিক নিয়ে আবার হাজির হবো ইনশাআল্লাহ্‌। ততক্ষণ পর্যন্ত সবাই ভাল থাকুন। আল্লাহ্‌ হাফেজ।