JavaScript Functions: Advanced
Pure function, recursion, tail call idea, composition, debounce প্যাটার্ন, memoization — বাংলায়।
ফাংশনের শেষ পর্ব — interview-এ সবচেয়ে চর্চিত আর বড় project-এ প্রতিদিনের টপিক: pure function, recursion, composition, debounce আর memoization।
Pure function
// Pure: একই input → একই output, বাইরে বদলায় না
function double(x) {
return x * 2;
}
console.log(double(5)); // 10
console.log(double(5)); // 10
// Impure: বাইরের state বদলায়
let count = 0;
function impure() {
count++; // বাইরের count-এ বদল
return count;
}
console.log(impure()); // 1
console.log(impure()); // 2Pure function — একই ইনপুটে সবসময় একই আউটপুট, আর বাইরের জগতে কোনো প্রভাব (side effect) নেই। এগুলো test করা সহজ ও নির্ভরযোগ্য।
Recursion
// নিজেকে নিজে ডাকা
function factorial(n) {
if (n <= 1) return 1; // base case
return n * factorial(n - 1); // recursive call
}
console.log(factorial(5)); // 120
// Fibonacci
function fib(n) {
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}
console.log(fib(10)); // 55Recursion-এ ফাংশন নিজেকে ডাকে। base case (শেষ শর্ত) না দিলে infinite loop হবে। tree-ভিত্তিক ডেটা (মেনু, folder structure) traversal-এর জন্য উপযুক্ত।
পারফরম্যান্স: recursion বড় n-এ ধীর। memoization বা loop দিয়ে উন্নত করা যায়:
function fibMemo(n, memo = {}) {
if (n <= 1) return n;
if (memo[n] !== undefined) return memo[n];
memo[n] = fibMemo(n - 1, memo) + fibMemo(n - 2, memo);
return memo[n];
}
console.log(fibMemo(40)); // দ্রুতFunction composition
const addGst = (p) => p * 1.15;
const format = (v) => v.toFixed(2) + " টাকা";
const compose = (...fns) => (x) =>
fns.reduceRight((acc, fn) => fn(acc), x);
const formattedPrice = compose(format, addGst);
console.log(formattedPrice(1000)); // "1150.00 টাকা"
// অথবা সরল
console.log(format(addGst(1000))); // "1150.00 টাকা"ফাংশনের ফলাফল পরের ফাংশনে — composition। addGst → format। ছোট ছোট pure function জুড়ে বড় কাজ।
Debounce (real-world)
// টাইপ করার পর ছোট বিরতিতে একবার চালায় (search box এর জন্য)
function debounce(fn, delay = 300) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
// ব্যবহার
const onSearch = debounce((query) => {
console.log("Search:", query);
}, 300);
onSearch("জ");
onSearch("জ অ");
onSearch("জ অ"); // 300ms পর একটাই চলেMemoization
function expensive(x) {
console.log("গণনা হচ্ছে...");
return x * x;
}
function memoize(fn) {
const cache = {};
return function (key) {
if (cache[key] !== undefined) return cache[key];
cache[key] = fn(key);
return cache[key];
};
}
const fastSquare = memoize(expensive);
console.log(fastSquare(5)); // গণনা হচ্ছে... 25
console.log(fastSquare(5)); // 25 (cache থেকে)Closure — সব প্যাটার্নের ভিত্তি
উপরের debounce/memoization-এ প্রতিবার call-এ নিজস্ব state (timer, cache) মনে রাখা হচ্ছে — এটিই closure। বিস্তারিত পরের অধ্যায় closures-this-এ।
| ধারণা | সারাংশ |
|---|---|
| Pure | same input → same output, no side effect |
| Recursion | base case থাকলে নিরাপদ |
| Composition | ছোট ফাংশনের জোড়া |
| Debounce | বিরতিতে ইভেন্ট কমানো |
| Memoization | result ক্যাশ করে দ্রুততর |
Recursive ফাংশনে base case না দিলে stack overflow — ব্রাউজার freeze করতে পারে।
"debounce/memoization function লিখো" — React-এ input search এর প্রতিদিনের প্রশ্ন। এই প্যাটার্নগুলো হাতে-কলমে আয়ত্ত করুন।
প্রথম ১০টি Fibonacci সংখ্যা অ্যারে নিয়ে একটি pure getSum লিখুন এবং debounce দিয়ে input event-এ চালান।