JavaScript Higher Order Functions are easy

Higher order function হলো এমন একটি ফাংশন যা আরেকটি ফাংশকে প্যারামিটার হিসাবে গ্রহন করে অথবা ফাংশনটি আরেকটি ফাংশন কে রিটার্ন করে।

জাভাস্ক্রিপ্ট এ অনেক Higher order function আছে যা আমরা ব্যবহার করছি কিন্তু এটা যে higher order function তা জানি না চলুন আজকে জেনে আসি কোন ফাংশন গুলোকে higher order function বলে।

উদাহরণ - ১

ধরুন আমাদের একটি অ্যারে আছে যার মধ্যে এলিমেন্ট এ কিছু সংখ্যা আছে ,

const number = [1, 2, 3];

এখন আমাদের টাস্ক হলো এই অ্যারে টির প্রত্যেকটি এলিমেন্ট কে দ্বিগুন করে রিটার্ন করা। চলুন জাভাস্ক্রিপ্টের higher order function ব্যবহার করা ছাড়া কাজ টা করি।

const number = [1, 2, 3]; const doubleNumber = []; for (let i = 0; i < number.length; i++) { doubleNumber.push(number[i] * 2); } console.log(doubleNumber);

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

Build in higher order function

আমরা জানি জাভাস্ক্রিপ্ট প্রোটোটাইপ বেইস ফাংশনাল প্রোগ্রামিং ল্যাঙ্গুয়েজ এখানে ইনহেরিটেন্স হয়ে থাকে প্রোটোটাইপ এর মাধ্যমে। আমরা যে অ্যারে ডিক্লেয়ার করি const arr = []; একে আমরা অন্য ভাবেও লিখতে পারি এটি যাস্ট সহজ একটি সিন্টেক্স, একে আমরা const arr = new Array(); এভাবে লিখতে পারি আমরা জানি new কিওয়ার্ড ব্যবহার করলে আমারা কিভাবে প্রোটোটাইপ থেকে প্রোপার্টি অ্যাক্সেস পাই তা আমার লেখা প্রোটোটাইপ ইনহেরিটেন্স এর আর্টিকেল টি দেখতে পারেন। অই প্রোটোটাইপ এ জাভাস্ক্রিপ্ট এর অনেক higher order function গুলো লেখা থাকে যা আমাদের কাজ কে সহজ, সুন্দর করে দিয়েছে। চলুন উপরের কাজ জাভাস্ক্রিপ্ট এর বিল্ট ইন higher order function দিয়ে করে আসি।

const number = [1, 2, 3]; const doubleNumber = number.map(function (item) { return item * 2; }); console.log(doubleNumber); //output - [2,4,6]

উপরের দেখুন যেখানে doubleNumber করা হয়েছে সেখানে number.map() ম্যাপ ফাংশন এর ভিতর একটি প্যারামিটার আকারে ফাংশন নেওয়া হয়েছে তাই এখানে higher order funcition ব্যবহার করা হয়েছে।

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

const number = [1, 2, 3]; const doubleNumber = number.map((item) => item * 2); console.log(doubleNumber); // output - [2,4,6]

কি মজার না বেপার টা।

উদাহরণ - ২

চলুন জাভাস্ক্রিপ্ট এর আরেকটি higher order functin filter() এর কাজ থেকে আসি। ধরুন আমাদের একটি বই এর অ্যারে অব অব্জেক্ট আছে যার থেকে আমরা ১০০ টাকার উপর বই গুলো পেতে চাচ্ছি এর জন্য আমার প্রথমে জেনেরিক সাধারন ওয়েতে দেখবে তার পর higher order functin filter() ব্যবহার করব।

const books = [ { name: 'Books - 1', price: 200, }, { name: 'Books - 2', price: 60, }, { name: 'Books - 3', price: 120, }, { name: 'Books - 4', price: 80, }, { name: 'Books - 5', price: 250, }, ]; const bookslessthen100 = []; for (let i = 0; i < books.length; i++) { if (books[i].price > 100) { bookslessthen100.push(books[i]); } } console.log(bookslessthen100); /* output - [ { name: 'Books - 1', price: 200, }, { name: 'Books - 3', price: 120, }, { name: 'Books - 5', price: 250, }, ]; */

উপরের এই একই কাজটি আমরা জাভাস্ক্রিপ্ট এর বিল্ট ইন ফাংশন filter() দিয়ে অনেক সহজে করে ফেলতে পারি। চলুন দেখা যাক , বলে রাখা ভালো ফিল্টার ফাংশন প্যারামিটার আকারে আরেকটি ফাংশন নেয়, তাই এটা higher order function এবং আমাদের মেইন অ্যারে কে কোনো পরিবর্তন না করে আমাদের ফিল্টার করা অ্যারে কে নতুন ভাবে রিটার্ন করে।

const bookslessthen100 = books.filter(function (item) { return item.price < 100; }); // es6 arrow function ব্যবহার করে implicit ভাবে রিটার্ন করলে const bookslessthen100 = books.filter((item) => item.price < 100); console.log(bookslessthen100); //output - উপরের মতো একই আসবে

আমার জেনেছি যে এই map() & filter() higher order function, আমরা জানি higher order function হতে হলেঃ-

  • একটি ফাংশন প্যারামিটার আকারে নিতে হবে।
  • অন্য একটি ফাংশন রিটার্ন করতে হবে
  • উপরের দুইটি ও হতে পারে।

চলুন আমরা একটি নিজেদের তৈরি করা ম্যাপ ফাংশন বানিয়ে নেই। তাহলে আমাদের বুঝতে আরো সহজ হবে কিভাবে higher order function কাজ করে।

const ourMap = function (arr, fn) { const newArr = []; for (let i = 0; i < arr.length; i++) { newArr.push(fn(arr[i])); } return newArr; };

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

এখন বলতে পারেন এখানে কি হলো সেই ত অনেক কোড লিখতে হলো আসলেই Array.map() কিন্তু এইরকম কিছু একটাই। এটা হচ্ছে স্ট্রাকচার এটা কে ব্যবহার করে ourMap() কল করে শুধু প্যারামিটার এ অ্যারে এবং ফাংশন দিয়ে আমার সহজ ভাবে কাজ টা করতে পারি। higher order function এভাবে আমাদের লাইফ ইজি করে। আমরা পূর্বে array দিয়ে তারপর ডট দিয়ে ব্যবহার করি। এখন আবার বলতে পারেন তাহলে আমার কেন ডট দিতে করি নাই কেন ফাংশন এ অ্যারে দিয়ে করেছি। কারন আমাদের তৈরি করা outMap কে ত আমরা প্রোটোটাইপ এ রাখি নি যদি অইখানে রেখে নিতাম তাহলে ডট ব্যবহার করে প্রোটোটাইপ থেকে ব্যবহার করতে পারতাম। আশা করি বুঝতে পারছেন। কিভাবে প্রোটোটাইপ কাজ করে আমাদের মেথড কে কিভাবে প্রোটোটাইপ রাখতে পারি সেটা জানার জন্য আমার লেখা প্রোটোটাইপ, ক্লাস ইত্যাদি আর্টিকেল টি দেখতে পারেন।