Functions — The Heart of JavaScript

"From First Steps to First-Class Citizens"

জাভাস্ক্রিপ্টে ফাংশন হলো "First-Class Citizens"। এর মানে হলো, তুমি একটি ফাংশনকে ভেরিয়েবলের মতো ব্যবহার করতে পারো, অন্য ফাংশনে পাস করতে পারো, আবার ফাংশন থেকে রিটার্নও করতে পারো।

যেই ডেভেলপার ফাংশন ভালো বোঝে, তার কাছে React, Node.js বা Functional Programming পানির মতো সহজ মনে হয়। চলো, জুনিয়র লেভেল থেকে আর্কিটেক্ট লেভেলে যাই।

১. Function আসলে কী? (The Blueprint)

ফাংশন হলো একটি Reusable Logic Machine। তুমি ইনপুট (Arguments) দেবে, সে প্রসেস করবে এবং আউটপুট (Return) দেবে।

কেন দরকার?

  • DRY Principle: Don't Repeat Yourself (একই কোড বারবার না লেখা)
  • Modularity: কোডকে ছোট ছোট লজিক্যাল ভাগে ভাগ করা
  • Maintenance: এক জায়গায় চেঞ্জ করলে সব জায়গায় আপডেট হয়ে যায়

২. Functions: Old vs Modern Syntax

A) Function Declaration (Hoisted)

এটি ট্র্যাডিশনাল উপায়। এর বিশেষ ক্ষমতা হলো Hoisting। অর্থাৎ, তুমি ফাংশন তৈরির আগেই তাকে কল করতে পারো।

greet(); // ✅ কাজ করবে! "Hello" প্রিন্ট হবে।

function greet() {
    console.log("Hello World");
}

B) Function Expression (Not Hoisted)

এখানে ফাংশনকে একটি ভেরিয়েবলের মধ্যে রাখা হয়। ভেরিয়েবল তৈরির আগে যেমন ব্যবহার করা যায় না, এটিও তেমন।

// sayHi(); // ❌ Error! (Cannot access before initialization)

const sayHi = function() {
    console.log("Hi there!");
};

C) Arrow Function (Modern & Clean) ✨

ES6 (2015) এ এটি এসেছে। এটি ছোট এবং স্মার্ট।

// Basic
const add = (a, b) => {
    return a + b;
};

// Senior Way (Implicit Return) - এক লাইনের হলে {} এবং return লাগে না
const multiply = (a, b) => a * b;

⚠️ Senior Warning (The this Trap):

Arrow Function দেখতে সুন্দর হলেও সব জায়গায় ব্যবহার করা যায় না। এর নিজস্ব this নেই। তাই Object Method বা Constructor হিসেবে Arrow Function ব্যবহার করবে না। (এটা আমরা OOP অধ্যায়ে বিস্তারিত দেখব)।

৩. Parameters: Smart Data Handling

জুনিয়ররা ম্যানুয়ালি চেক করে ডেটা আছে কিনা। সিনিয়ররা Default Parameters এবং Rest Operator ব্যবহার করে।

Default Parameters (No more undefined bugs)

// ❌ Old Way
function welcome(user) {
    if (user === undefined) user = "Guest";
    console.log("Hello " + user);
}

// ✅ Modern Way
function welcome(user = "Guest") {
    console.log(`Hello ${user}`);
}

Rest Parameters ...args (Modern) vs arguments (Old)

আগে আমরা arguments অবজেক্ট ব্যবহার করতাম, যা অ্যারে-র মতো দেখতে হলেও আসলে অ্যারে না। এখন আমরা Rest Operator ব্যবহার করি।

// যেকোনো সংখ্যক সংখ্যার যোগফল বের করার ফাংশন
function sum(...numbers) {
    // numbers এখন একটি আসল Array [1, 2, 3, 4, 5]
    return numbers.reduce((total, num) => total + num, 0);
}

console.log(sum(1, 2, 3, 4, 5)); // 15

৪. Higher Order Functions (HOF) & Callbacks

জাভাস্ক্রিপ্টের আসল পাওয়ার এখানেই।

সংজ্ঞা: যে ফাংশন অন্য ফাংশনকে আর্গুমেন্ট হিসেবে নেয় অথবা ফাংশন রিটার্ন করে, তাকে Higher Order Function বলে।

Callback Function (The Servant)

যাকে হুকুম দেওয়া হয় কাজ শেষে কল করার জন্য।

function processOrder(orderId, callback) {
    console.log(`Order ${orderId} processing...`);
    
    // মনে করো ৩ সেকেন্ড সময় লাগছে
    setTimeout(() => {
        callback(); // কাজ শেষ, এখন কলব্যাক চালাও
    }, 3000);
}

processOrder(101, () => {
    console.log("Order Completed! Send Email.");
});

এখানে setTimeout হলো Higher Order Functions (HOF) এবং ভেতরের ফাংশনটি হলো Callback.

৫. IIFE (Immediately Invoked Function Expression)

ফাংশন বানানোর সাথে সাথেই এক্সিকিউট হয়ে যাবে।

কেন দরকার? গ্লোবাল ভেরিয়েবল পলিউশন রোধ করতে এবং কোড প্রাইভেট রাখতে।

(function() {
    const secretCode = "123456";
    console.log("System initialized securely.");
})();

// console.log(secretCode); // ❌ Error! বাইরে থেকে এক্সেস নেই।

যদিও মডার্ন Module সিস্টেমে এর ব্যবহার কমেছে, কিন্তু লিগ্যাসি কোড বুঝতে এটা জানতেই হবে।

৬. Pure vs Impure Functions (Architectural Concept)

একজন সিনিয়রের কোড ক্লিন হওয়ার রহস্য হলো Pure Functions।

Pure Function ✅ Impure Function ❌
ইনপুট একই হলে আউটপুট সবসময় একই হবে ইনপুট এক হলেও আউটপুট ভিন্ন হতে পারে (যেমন Date.now())
বাইরের কোনো ভেরিয়েবল পরিবর্তন করে না (No Side Effects) বাইরের ভেরিয়েবল বা গ্লোবাল স্টেট বদলে দেয়

Example:

// ✅ Pure: শুধু ইনপুট নিয়ে কাজ করে
const add = (a, b) => a + b;

// ❌ Impure: বাইরের total কে বদলে দিচ্ছে
let total = 0;
const addToTotal = (num) => {
    total += num; // Side Effect!
};

উপদেশ: তোমার অ্যাপ্লিকেশনের ৮০% ফাংশন যেন Pure হয়। এতে টেস্টিং এবং ডিবাগিং সহজ হয়।

🧠 ৭. Senior Level Interview Questions

Q: Function Declaration এবং Expression এর মূল পার্থক্য কী?

A: Declaration hoisted হয় (উপরে উঠে যায়), তাই ডিক্লেয়ার করার আগে কল করা যায়। Expression ভেরিয়েবলের মতো কাজ করে, তাই ইনিশিয়ালাইজেশনের আগে কল করা যায় না।

Q: arguments অবজেক্ট এবং rest parameter এর পার্থক্য কী?

A: arguments একটি array-like object (Array method কাজ করে না), আর rest (...) একটি রিয়েল Array। তাছাড়া Arrow function-এ arguments কাজ করে না।

💻 ৮. Coding Challenge (Logic Building)

নিচের সমস্যাগুলো সলভ করার চেষ্টা করো:

🔥 Problem 1: Vowel Counter (Modern Way)

const countVowels = (str) => {
    const vowels = ['a', 'e', 'i', 'o', 'u'];
    return str.toLowerCase()
              .split('')
              .filter(char => vowels.includes(char))
              .length;
};
console.log(countVowels("Hello World")); // Output: 3

🔥 Problem 2: Function Returning Function (Closure)

এমন একটি ফাংশন বানাও যা বেস নম্বর মনে রাখে।

function createMultiplier(multiplier) {
    return function (number) {
        return number * multiplier;
    };
}

const double = createMultiplier(2);
const triple = createMultiplier(3);

console.log(double(5)); // 10
console.log(triple(5)); // 15

🚀 অধ্যায় ৩ সারাংশ (Summary)

আমরা শিখলাম:

  • Declarations সবার আগে লোড হয় (Hoisting)
  • Arrow Functions ক্লিন সিনট্যাক্স দেয় কিন্তু this হ্যান্ডলিং ভিন্ন
  • Parameters: Default এবং Rest ব্যবহার করা মডার্ন প্র্যাকটিস
  • Power: Callback এবং HOF দিয়েই জাভাস্ক্রিপ্টের আসল কাজ হয়
  • Clean Code: সবসময় Pure Function লেখার চেষ্টা করবে

Next Step: ফাংশন তো শিখলাম, কিন্তু ফাংশনের ভেতরের ভেরিয়েবলগুলো মেমোরিতে কীভাবে থাকে? কে কাকে এক্সেস করতে পারে? এটা বোঝার জন্য পরের অধ্যায়টি সবচেয়ে গুরুত্বপূর্ণ— "Scope, Hoisting & Execution Context"।

🔒 কপিরাইট সুরক্ষিত কন্টেন্ট 🔒

কপি, স্ক্রিনশট, প্রিন্ট করা সম্পূর্ণ নিষিদ্ধ।