📜 JavaScript পরিচিতি ও বেসিক ধারণা — সম্পূর্ণ নোট

এই সেকশনে JavaScript-এর ইতিহাস, সংস্করণ, কীভাবে চালাতে হয় এবং প্রথম কোড লেখার সবকিছু বাংলায় বিস্তারিত আলোচনা করা হয়েছে।


🔷 What is JavaScript? — JavaScript কী?

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

JavaScript একটি Interpreted ভাষা — অর্থাৎ কোড আগে compile করতে হয় না, ব্রাউজার সরাসরি পড়ে চালিয়ে দেয়। এটি Lightweight এবং Object-Oriented বৈশিষ্ট্যসম্পন্ন।

তিনটি ভাষার ভূমিকা মনে রাখো:
HTML → "এখানে একটা বাটন আছে।" (কাঠামো)
CSS  → "বাটনটা নীল রঙের।" (সাজসজ্জা)
JS    → "বাটনে ক্লিক করলে মেসেজ দেখাবে।" (কার্যকলাপ)

JavaScript দিয়ে যা করা যায়:

কাজের ধরন উদাহরণ
ওয়েবপেজ ইন্টারেক্টিভ করা বাটন ক্লিক, ফর্ম যাচাই, মেনু খোলা
ডায়নামিক কন্টেন্ট নতুন ডেটা লোড করা, পেজ reload ছাড়াই পরিবর্তন
Animation ও Effects স্লাইডশো, পপআপ, স্ক্রল অ্যানিমেশন
Server-side প্রোগ্রামিং Node.js দিয়ে backend তৈরি
Mobile App React Native দিয়ে Android/iOS অ্যাপ
Game Development ব্রাউজার গেম তৈরি
⚠️ Java ≠ JavaScript: Java এবং JavaScript সম্পূর্ণ আলাদা দুটি ভাষা — নামে মিল থাকলেও এদের মধ্যে কোনো সম্পর্ক নেই। এটি একটি অত্যন্ত সাধারণ ভুল ধারণা।

🔷 History of JavaScript — JavaScript-এর ইতিহাস

JavaScript-এর জন্ম একটি মজার গল্প। মাত্র ১০ দিনে তৈরি হওয়া এই ভাষাটি আজ বিশ্বের সবচেয়ে জনপ্রিয় প্রোগ্রামিং ভাষাগুলোর একটি।

সময়রেখা Timeline

সাল ঘটনা
১৯৯৫ Brendan Eich Netscape কোম্পানিতে মাত্র ১০ দিনে JavaScript তৈরি করেন। প্রথম নাম ছিল Mocha
১৯৯৫ Mocha → LiveScript নামে release হয়।
১৯৯৫ LiveScript → JavaScript নামকরণ হয় (Java-এর জনপ্রিয়তাকে কাজে লাগাতে)।
১৯৯৬ Microsoft নিজেদের ব্রাউজারের জন্য JScript তৈরি করে।
১৯৯৭ ECMAScript (ES1) — JavaScript-এর প্রথম আন্তর্জাতিক মান প্রতিষ্ঠিত হয়।
২০০৯ Node.js তৈরি হয় — JavaScript এখন সার্ভারেও চলতে পারে।
২০১৫ ES6 (ES2015) — সবচেয়ে বড় আপডেট। let, const, Arrow Function ইত্যাদি যোগ হয়।
২০২৩+ প্রতি বছর নতুন ফিচার যোগ হচ্ছে। JavaScript এখন বিশ্বের #১ জনপ্রিয় ভাষা।
মজার তথ্য: Brendan Eich মাত্র ১০ দিনে JavaScript তৈরি করেন — এবং সেই ভাষা আজ ৩০ বছর পরেও ইন্টারনেটের মেরুদণ্ড হয়ে আছে!

🔷 JavaScript Versions — JavaScript-এর সংস্করণ

JavaScript-এর official নাম হলো ECMAScriptECMA International নামের সংস্থা এই ভাষার মান নির্ধারণ করে। প্রতিটি নতুন সংস্করণকে ES + সংখ্যা দিয়ে চেনা যায়।

সংস্করণ সাল গুরুত্বপূর্ণ সংযোজন গুরুত্ব
ES1 ১৯৯৭ প্রথম মান — মৌলিক ভাষা কাঠামো ঐতিহাসিক
ES3 ১৯৯৯ Regular Expression, try/catch গুরুত্বপূর্ণ
ES5 ২০০৯ strict mode, JSON সাপোর্ট, Array methods ⭐ শিখতে হবে
ES6 / ES2015 ২০১৫ let, const, Arrow Function, Class, Template Literal, Promise ⭐⭐ সবচেয়ে গুরুত্বপূর্ণ
ES7 / ES2016 ২০১৬ async/await, Exponentiation (**) ⭐ দরকারি
ES8 / ES2017 ২০১৭ Object.entries(), String padding দরকারি
ES2020+ ২০২০~ Optional Chaining (?.), Nullish Coalescing (??) আধুনিক JS
শেখার পরামর্শ: প্রথমে ES5 এর বেসিক, তারপর ES6 এর নতুন ফিচারগুলো ভালো করে শেখো — এই দুটো দিয়েই ৯০% কাজ করা যায়।
⚠️ Browser Compatibility: পুরনো ব্রাউজার নতুন ES ফিচার নাও চিনতে পারে। তাই বড় প্রজেক্টে Babel নামের টুল দিয়ে পুরনো সংস্করণে রূপান্তর করা হয়।

🔷 How to Run JavaScript — JavaScript কীভাবে চালাবে?

JavaScript চালানোর বেশ কয়েকটি উপায় আছে। শুরুতে সবচেয়ে সহজ পদ্ধতিগুলো জানো:

পদ্ধতি ১ — Browser Console সবচেয়ে সহজ

যেকোনো ব্রাউজারে (Chrome/Firefox) F12 চাপো → Console ট্যাবে ক্লিক করো → সরাসরি JavaScript লিখে Enter চাপো — কোড চলে যাবে।

// Browser Console-এ লিখে Enter চাপো: 2 + 3 // → 5 "হ্যালো " + "বিশ্ব" // → হ্যালো বিশ্ব Math.max(10, 20, 5) // → 20

পদ্ধতি ২ — HTML ফাইলে লিখে Browser-এ খোলো শেখার জন্য ভালো

Notepad বা যেকোনো text editor-এ একটি .html ফাইল তৈরি করো, ভেতরে <script> ট্যাগে JS লিখো, তারপর ফাইলটি ব্রাউজারে খোলো।

<!DOCTYPE html> <html> <body> <script> console.log("আমার প্রথম JavaScript!"); alert("স্বাগতম!"); </script> </body> </html>

পদ্ধতি ৩ — VS Code + Browser (Live Server) পেশাদার পদ্ধতি

VS Code ডাউনলোড করো → Live Server extension ইনস্টল করো → HTML ফাইলে right-click করে "Open with Live Server" ক্লিক করো। কোড পরিবর্তন করলে ব্রাউজার স্বয়ংক্রিয়ভাবে আপডেট হবে।

VS Code Download : https://code.visualstudio.com Live Server : VS Code Extensions থেকে খুঁজে Install করো

পদ্ধতি ৪ — Node.js (Terminal-এ) Advanced

Node.js ইনস্টল করলে ব্রাউজার ছাড়াই Terminal-এ JavaScript চালানো যায়। এটি একটু advanced — শুরুতে শুধু জানলেই হবে।

// Terminal-এ: node script.js // অথবা সরাসরি: node > console.log("হ্যালো Node!") // → হ্যালো Node!
শুরু করার পরামর্শ: প্রথমে Browser Console দিয়ে ছোট ছোট কোড পরীক্ষা করো। তারপর VS Code + Live Server সেটআপ করো।

🔷 JavaScript কোথায় কাজ করে?

JavaScript মূলত দুটি পরিবেশে কাজ করে:

পরিবেশ কীভাবে চলে? কী কাজে লাগে? উদাহরণ
Client-side (Browser) ব্রাউজারের JavaScript Engine চালায় UI ইন্টারেক্টিভ করা, DOM পরিবর্তন Chrome (V8), Firefox (SpiderMonkey)
Server-side (Node.js) Node.js Runtime চালায় API তৈরি, ডেটাবেজ, ফাইল পরিচালনা Express.js, Next.js backend

JavaScript Engine কী? Engine

প্রতিটি ব্রাউজারে একটি JavaScript Engine থাকে যা JS কোড পড়ে কম্পিউটারের বোঝার মতো ভাষায় রূপান্তর করে।

ব্রাউজার JavaScript Engine
Google Chrome V8
Mozilla Firefox SpiderMonkey
Safari JavaScriptCore (Nitro)
Microsoft Edge V8 (Chromium-based)
Node.js V8 (Chrome-এর Engine ব্যবহার করে)
মনে রাখো: Node.js মূলত Chrome-এর V8 Engine ব্যবহার করে — তাই ব্রাউজার ছাড়াও Terminal-এ JavaScript চালানো সম্ভব হয়।
⚠️ শুরুতে শুধু Browser-এ মনোযোগ দাও। Node.js পরে শিখবে — আগে Browser JavaScript ভালো করো।

🔷 HTML-এ JavaScript যোগ করার উপায়

JavaScript তিনভাবে HTML-এ লেখা যায়:

১. Inline JavaScript এড়িয়ে চলো

সরাসরি HTML ট্যাগের ভেতরে লেখা হয়। ছোট পরীক্ষায় কাজে লাগলেও বড় প্রজেক্টে এটি এড়িয়ে চলা উচিত।

<button onclick="alert('হ্যালো!')">ক্লিক করো</button> <p onmouseover="this.style.color='red'">মাউস রাখো</p>

২. Internal JavaScript শেখার জন্য ভালো

HTML ফাইলের ভেতরে <script> ট্যাগে লেখা হয়। শেখার সময় এটাই বেশি ব্যবহার করা হয়।

<!DOCTYPE html> <html> <body> <h1>আমার ওয়েবসাইট</h1> <!-- ✅ script ট্যাগ সবসময় </body> এর আগে --> <script> console.log("হ্যালো, JavaScript!"); document.querySelector("h1").style.color = "blue"; </script> </body> </html>

৩. External JavaScript সবচেয়ে ভালো পদ্ধতি

আলাদা .js ফাইলে কোড লিখে HTML-এ src দিয়ে লিঙ্ক করা হয়। এটাই সবচেয়ে পেশাদার ও পরিষ্কার পদ্ধতি।

<!-- index.html ফাইলে --> <body> <h1>আমার ওয়েবসাইট</h1> <!-- আলাদা JS ফাইল লিঙ্ক করা হচ্ছে --> <script src="script.js"></script> </body>
/* script.js ফাইলে */ console.log("বাইরের ফাইল থেকে চলছি!"); document.querySelector("h1").textContent = "JS পরিবর্তন করেছে!";

defer ও async — কখন ব্যবহার করবে? Bonus

<head>-এ script রাখলে defer ব্যবহার করো — এতে HTML পুরো লোড হওয়ার পরে JS চলবে।

<!-- head-এ রাখলে defer ব্যবহার করো --> <head> <script src="script.js" defer></script> </head> <!-- body-র শেষে রাখলে defer লাগে না --> <body> ... <script src="script.js"></script> </body>
ভালো অভ্যাস: <script> ট্যাগ সবসময় </body> এর ঠিক আগে রাখো — এতে পেজ আগে লোড হয়, তারপর JavaScript চলে।

🔷 প্রথম JavaScript কোড লেখা

JavaScript শুরু করার জন্য এই Output পদ্ধতিগুলো আগে ভালো করে জানো:

১. console.log() সবচেয়ে বেশি ব্যবহৃত

ব্রাউজারের Console-এ কিছু দেখাতে ব্যবহার করো। F12 চেপে Developer Tools খুলে Console ট্যাবে দেখো।

console.log("হ্যালো বিশ্ব!"); // → হ্যালো বিশ্ব! console.log(100 + 50); // → 150 console.log("বয়স:", 20); // → বয়স: 20 console.log(true); // → true // একাধিক মান একসাথে: console.log("নাম:", "ফারিদ", "বয়স:", 20); // → নাম: ফারিদ বয়স: 20

২. alert() পপআপ

ব্রাউজারে পপআপ মেসেজ দেখায়। ব্যবহারকারী OK না চাপা পর্যন্ত পেজ থামে।

alert("স্বাগতম!"); alert("তোমার স্কোর: " + 95);

৩. document.write() সাবধানে ব্যবহার করো

সরাসরি ওয়েবপেজে লেখা দেখায়। তবে সতর্কতা — পেজ লোডের পরে ব্যবহার করলে পুরো পেজ মুছে যায়।

document.write("এটা পেজে দেখাবে!"); document.write("<h2>শিরোনাম</h2>"); // HTML লেখাও যায়

৪. innerHTML সবচেয়ে কার্যকর

নির্দিষ্ট HTML element-এর ভেতরে কন্টেন্ট বসাতে বা পরিবর্তন করতে ব্যবহার হয়। বাস্তব প্রজেক্টে এটাই সবচেয়ে বেশি ব্যবহৃত।

<!-- HTML-এ একটি div আছে --> <div id="output"></div> <script> // JS দিয়ে সেই div-এ লেখা বসানো হলো document.getElementById("output").innerHTML = "হ্যালো!"; </script>
কোনটা কখন?
Debug করতে → console.log()
ব্যবহারকারীকে জানাতে → alert()
পেজে কন্টেন্ট বসাতে → innerHTML

🔷 JavaScript-এ Comment

Comment হলো কোডের ভেতরে নোট লেখার উপায়। ব্রাউজার এটা পড়ে না বা চালায় না — শুধু প্রোগ্রামারের জন্য।

১. Single-line Comment — // একলাইন

// এটা একটি single-line comment let name = "ফারিদ"; // এখানেও comment করা যায় // নিচের লাইন চলবে না (comment করা): // console.log("এটা চলবে না");

২. Multi-line Comment — /* */ বহুলাইন

/* এটা একটি multi-line comment। এখানে একাধিক লাইনে বিস্তারিত ব্যাখ্যা লেখা যায়। তৈরি করেছেন: ফারিদ তারিখ: ২০২৫ */ let price = 100; /* মূল্য টাকায় */

৩. Comment দিয়ে কোড বন্ধ রাখা Debugging Trick

Debug করার সময় কোনো লাইন সাময়িকভাবে বন্ধ রাখতে Comment ব্যবহার করো।

let total = 100; // total = total * 2; // এই লাইনটা এখন বন্ধ console.log(total); // → 100
ভালো অভ্যাস: নিজের কোডে Comment লেখো — পরে নিজে বুঝতে সহজ হবে। দলগত কাজে Comment অপরিহার্য।

🔷 দ্রুত রেফারেন্স — JavaScript বেসিক

বিষয় কমান্ড / তথ্য উদাহরণ / নোট
Console-এ দেখানো console.log() Debug-এর জন্য সবচেয়ে বেশি ব্যবহৃত
পপআপ দেখানো alert() ব্যবহারকারীকে জানাতে
পেজে কন্টেন্ট বসানো innerHTML বাস্তব কাজে সবচেয়ে বেশি ব্যবহৃত
Single-line Comment // নোট একলাইনের ব্যাখ্যা
Multi-line Comment /* নোট */ একাধিক লাইনের ব্যাখ্যা
External JS যোগ করা <script src="app.js"></script> সবচেয়ে ভালো পদ্ধতি
Defer ব্যবহার <script defer> HTML লোডের পরে JS চালায়
সবচেয়ে গুরুত্বপূর্ণ সংস্করণ ES5 ও ES6 ES6 = ২০১৫, সবচেয়ে বড় আপডেট
JavaScript-এর জনক Brendan Eich ১৯৯৫ সালে মাত্র ১০ দিনে তৈরি
Official নাম ECMAScript ECMA International কর্তৃক মান নির্ধারিত
Chrome-এর JS Engine V8 Node.js-ও V8 ব্যবহার করে

🧠 নিজেকে যাচাই করো

1. JavaScript কী?

2. JS কোথায় লেখা যায়?

3. console.log() কী করে?

✏️ Task — এখন তুমি করো

Browser console খোলো (F12)। console.log() দিয়ে তোমার নাম, বয়স ও শহর print করো।

ধাপ 1🏗️ Real Project — Interactive Portfolio

Portfolio-এ প্রথম JavaScript যোগ করো — welcome message দেখাও।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio-এ JS যোগ করো — welcome message button।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

📦 All About JavaScript Variables — সম্পূর্ণ নোট

এই সেকশনে JavaScript Variable কী, কীভাবে তৈরি করতে হয়, Hoisting, Scope সহ সবকিছু বাংলায় বিস্তারিত আলোচনা করা হয়েছে।


🔷 Variable কী?

Variable হলো একটি নামওয়ালা বাক্স বা পাত্র — যেখানে তথ্য রাখা যায়, পড়া যায় এবং প্রয়োজনে পরিবর্তন করা যায়।

বাস্তব উদাহরণ — একটি দোকানের হিসাবের খাতায় যেমন "মোট বিক্রয়", "মজুদ পণ্য", "লাভ" আলাদা ঘরে লেখা থাকে — প্রোগ্রামে সেগুলোই Variable।

let product = "চাল"; // product বাক্সে "চাল" রাখা হলো let quantity = 50; // quantity বাক্সে 50 রাখা হলো let price = 65.50; // price বাক্সে 65.50 রাখা হলো console.log(product); // → চাল console.log(quantity * price); // → 3275
Variable মনে রাখার উপায়: Variable হলো লেবেলওয়ালা কৌটা — কৌটায় যা রাখো সেটাই তার মান (value), লেবেলটাই তার নাম (name)

Declaration ও Initialization গুরুত্বপূর্ণ পার্থক্য

পদক্ষেপ অর্থ উদাহরণ
Declaration Variable-এর নাম তৈরি করা let score;
Initialization প্রথমবার মান দেওয়া let score = 0;
Assignment পরে নতুন মান দেওয়া score = 100;
let score; // Declaration — শুধু নাম তৈরি হলো console.log(score); // → undefined (মান নেই) score = 50; // Assignment — প্রথম মান দেওয়া হলো console.log(score); // → 50 score = 90; // Re-assignment — নতুন মান দেওয়া হলো console.log(score); // → 90

🔷 Variable Declarations — Variable তৈরির তিনটি উপায়

JavaScript-এ Variable তৈরি করতে তিনটি keyword ব্যবহার হয়:

১. var পুরনো পদ্ধতি — এড়িয়ে চলো

ES6 (2015) আসার আগে JavaScript-এ var ছাড়া আর কোনো উপায় ছিল না। এটি Function-scoped এবং একই নামে বারবার declare করা যায়, যা অনেক সময় অপ্রত্যাশিত bug তৈরি করে।

var city = "ঢাকা"; var city = "চট্টগ্রাম"; // ✅ একই নামে আবার declare — কোনো error নেই! console.log(city); // → চট্টগ্রাম // সমস্যা: if block-এর ভেতরের var বাইরেও দেখা যায় if (true) { var insideVar = "আমি var"; } console.log(insideVar); // → আমি var ⚠️ (block-এর বাইরেও accessible!)
⚠️ var ব্যবহার করো না। এর Function-scope আচরণ অনেক সময় অপ্রত্যাশিত ফলাফল দেয়। নতুন কোডে সবসময় let বা const ব্যবহার করো।

২. let আধুনিক — সবচেয়ে বেশি ব্যবহৃত

ES6-এ আসা let হলো আধুনিক পরিবর্তনযোগ্য Variable। এটি Block-scoped{ } এর বাইরে দেখা যায় না।

let score = 0; score = 10; // ✅ মান পরিবর্তন করা যায় score = 25; console.log(score); // → 25 // let একই নামে আবার declare করা যায় না: // let score = 50; // ❌ SyntaxError! // Block-scope — if-এর ভেতরের let বাইরে নেই: if (true) { let inside = "আমি let"; console.log(inside); // → আমি let } // console.log(inside); // ❌ ReferenceError — বাইরে নেই!

৩. const স্থায়ী মানের জন্য

স্থায়ী তথ্যের জন্য। একবার মান দিলে আর পরিবর্তন করা যাবে না। Declare করার সময়ই মান দিতে হবে

const PI = 3.1416; // PI = 3.14; // ❌ TypeError — const পরিবর্তন করা যায় না! const COUNTRY = "বাংলাদেশ"; console.log(COUNTRY); // → বাংলাদেশ // const ছাড়া declare করা যায় না: // const x; // ❌ SyntaxError — মান দিতেই হবে! // ⚠️ তবে Object-এর ভেতরের মান পরিবর্তন করা যায়: const user = { name: "রাহেলা" }; user.name = "করিম"; // ✅ এটা চলবে (object-এর property পরিবর্তন) console.log(user.name); // → করিম
Object ও Array-এর ক্ষেত্রে: const মানে Variable-এর reference স্থায়ী — তাই Object-এর ভেতরের property বা Array-এর item পরিবর্তন করা যায়, কিন্তু পুরো নতুন Object বা Array assign করা যায় না।

🔷 var, let, const — পার্থক্য এক নজরে

বৈশিষ্ট্য var let const
Scope (কার্যক্ষেত্র) Function Scope Block Scope Block Scope
মান পরিবর্তন (Reassign) ✅ পারবে ✅ পারবে ❌ পারবে না
আবার Declare (Redeclare) ✅ পারবে ❌ পারবে না ❌ পারবে না
Declare ছাড়াই মান ব্যবহার ✅ (undefined আসে) ❌ Error আসে ❌ Error আসে
Hoisting ✅ (undefined সহ) ✅ (TDZ — Error) ✅ (TDZ — Error)
Declare-এ মান বাধ্যতামূলক ❌ না ❌ না ✅ হ্যাঁ, বাধ্যতামূলক
কখন ব্যবহার করবে? ❌ এড়িয়ে চলো ✅ পরিবর্তনযোগ্য মান ✅ স্থায়ী মান
সহজ নিয়ম মনে রাখো:
→ সবসময় আগে const চেষ্টা করো।
→ মান পরে বদলাতে হবে মনে হলে let ব্যবহার করো।
var ভুলে যাও।

🔷 Naming Rules — Variable-এর নাম দেওয়ার নিয়ম

Variable-এর নাম দেওয়ার সময় JavaScript-এর নির্দিষ্ট নিয়ম মানতে হয়:

বাধ্যতামূলক নিয়ম অবশ্যই মানতে হবে

নিয়ম সঠিক উদাহরণ ✅ ভুল উদাহরণ ❌
অক্ষর, _, বা $ দিয়ে শুরু করতে হবে name, _count, $price 1name, 2age
Space ব্যবহার করা যাবে না firstName, user_name first name
হাইফেন (-) ব্যবহার করা যাবে না totalPrice total-price
Reserved word ব্যবহার করা যাবে না myLet, constValue let, const, if
Case-sensitive (বড়-ছোট হাতে পার্থক্য আছে) ageAgeAGE
// ✅ সঠিক নাম let totalScore = 100; let _privateVar = "hidden"; let $dollarSign = 50; let userName2 = "রাহেলা"; // ❌ ভুল নাম // let 2score = 10; → সংখ্যা দিয়ে শুরু // let total score = 10; → Space আছে // let total-score = 10; → হাইফেন আছে // let if = 10; → Reserved word

গুরুত্বপূর্ণ Reserved Words নাম হিসেবে ব্যবহার নিষিদ্ধ

var let const function return if else for while do switch case break continue class new this true false null undefined typeof delete import export

Naming Convention — কোন স্টাইলে নাম দেবে? Best Practice

স্টাইল উদাহরণ কখন ব্যবহার?
camelCase totalScore, isLoggedIn, getUserName ✅ সাধারণ Variable ও Function — সবচেয়ে জনপ্রিয়
UPPER_CASE MAX_SIZE, API_URL, TAX_RATE Constant — যে মান কখনো বদলাবে না
PascalCase UserProfile, ProductItem Class ও Constructor Function-এর জন্য
_underscore _privateData Private বোঝাতে (অনানুষ্ঠানিক)
ভালো নাম দেওয়ার অভ্যাস করো:
→ নাম দেখেই বোঝা যাওয়া উচিত কী রাখা আছে।
x = 25 — বোঝা যাচ্ছে না।
studentAge = 25 — স্পষ্ট ও পরিষ্কার। ✅

🔷 Variable-এ কী রাখা যায়? — Data Types

JavaScript একটি Dynamically Typed ভাষা — Variable declare করার সময় ধরন বলতে হয় না, মান দিলে JavaScript নিজেই বুঝে নেয়।

let data = "হ্যালো"; // এখন String data = 42; // এখন Number — JS আপত্তি করে না! data = true; // এখন Boolean

Primitive Data Types মৌলিক ধরন

ধরন কী রাখে? উদাহরণ typeof
String লেখা বা টেক্সট "হ্যালো", 'ঢাকা' "string"
Number যেকোনো সংখ্যা 42, 3.14, -10 "number"
BigInt অনেক বড় সংখ্যা 9007199254740991n "bigint"
Boolean সত্য বা মিথ্যা true, false "boolean"
null ইচ্ছাকৃত খালি null "object" ⚠️
undefined মান দেওয়া হয়নি undefined "undefined"
Symbol অনন্য পরিচয় Symbol("id") "symbol"
let name = "করিম"; // String let age = 22; // Number let height = 5.8; // Number (দশমিক) let isStudent = true; // Boolean let address = null; // null — এখনো ঠিকানা নেই let phone; // undefined — মান দেওয়া হয়নি console.log(typeof name); // → string console.log(typeof age); // → number console.log(typeof isStudent); // → boolean console.log(typeof address); // → object ⚠️ (JS-এর পুরনো bug) console.log(typeof phone); // → undefined

Non-Primitive (Reference) Types জটিল ধরন

ধরন কী রাখে? উদাহরণ
Object Key-Value জোড়ায় একাধিক তথ্য { name: "করিম", age: 22 }
Array তালিকা আকারে একাধিক মান ["ঢাকা", "চট্টগ্রাম", "সিলেট"]
Function পুনরায় ব্যবহারযোগ্য কোড ব্লক function greet() { ... }
// Object — একাধিক তথ্য একসাথে const student = { name: "রাহেলা", age: 20, city: "ঢাকা" }; console.log(student.name); // → রাহেলা // Array — তালিকা const fruits = ["আম", "কলা", "লিচু"]; console.log(fruits[0]); // → আম console.log(fruits.length); // → 3
⚠️ null vs undefined পার্থক্য:
null → আমি জেনেশুনে খালি রেখেছি।
undefined → মান দেওয়াই হয়নি (JavaScript নিজে বসায়)।

🔷 Hoisting — উপরে তোলা

Hoisting হলো JavaScript-এর একটি বিশেষ আচরণ — কোড চালানোর আগে JavaScript সব Declaration গুলো সেই Scope-এর একদম উপরে নিয়ে যায়। তবে var, letconst ভিন্নভাবে আচরণ করে।

var এর Hoisting undefined সহ উঠে যায়

// তুমি যা লিখেছো: console.log(city); // → undefined (Error নয়!) var city = "ঢাকা"; console.log(city); // → ঢাকা // JavaScript আসলে এভাবে দেখে: var city; // ← JS নিজেই উপরে তুলে নিয়েছে console.log(city); // → undefined city = "ঢাকা"; console.log(city); // → ঢাকা

letconst এর Hoisting — Temporal Dead Zone (TDZ) TDZ

letconst-ও Hoisting হয়, কিন্তু এরা Temporal Dead Zone (TDZ)-এ থাকে। Declaration-এর আগে access করলে ReferenceError আসে।

// let — TDZ-এ থাকে console.log(score); // ❌ ReferenceError: Cannot access 'score' before initialization let score = 100; // const — একইভাবে TDZ console.log(PI); // ❌ ReferenceError const PI = 3.14;

Function Hoisting পুরো Function উপরে যায়

Function Declaration সম্পূর্ণভাবে উপরে চলে যায় — তাই define করার আগেই call করা যায়।

// Function define করার আগেই call করা যাচ্ছে: sayHello(); // → হ্যালো! function sayHello() { console.log("হ্যালো!"); }

Hoisting সারসংক্ষেপ এক নজরে

ধরন Hoist হয়? আগে ব্যবহার করলে?
var ✅ হ্যাঁ undefined পাবে
let ✅ হ্যাঁ (TDZ) ReferenceError
const ✅ হ্যাঁ (TDZ) ReferenceError
Function Declaration ✅ সম্পূর্ণ ✅ ঠিকঠাক কাজ করবে
Hoisting এড়ানোর ভালো অভ্যাস: সবসময় Variable ব্যবহার করার আগে declare ও initialize করো — তাহলে Hoisting নিয়ে চিন্তা করতে হবে না।

🔷 Variable Scopes — কার্যক্ষেত্র

Scope হলো একটি Variable কোথায় কোথায় দেখা বা ব্যবহার করা যাবে তার সীমানা। JavaScript-এ তিন ধরনের Scope আছে।

১. Global Scope সর্বত্র দেখা যায়

কোনো Function বা Block-এর বাইরে declare করা Variable হলো Global। পুরো প্রোগ্রামের যেকোনো জায়গা থেকে এটি ব্যবহার করা যায়।

let country = "বাংলাদেশ"; // Global Variable function showCountry() { console.log(country); // ✅ function-এর ভেতরে দেখা যাচ্ছে } showCountry(); // → বাংলাদেশ console.log(country); // → বাংলাদেশ (বাইরেও দেখা যাচ্ছে)
⚠️ সতর্কতা: Global Variable বেশি ব্যবহার করলে বড় প্রজেক্টে সমস্যা হয় — যেকোনো জায়গা থেকে মান পরিবর্তন হয়ে যেতে পারে। প্রয়োজন না হলে Global Variable এড়িয়ে চলো।

২. Function Scope Function-এর ভেতরে সীমাবদ্ধ

Function-এর ভেতরে declare করা Variable শুধু সেই Function-এর ভেতরেই থাকে। বাইরে থেকে access করা যায় না।

function calculateArea() { let length = 10; // Function-scoped Variable let width = 5; let area = length * width; console.log(area); // → 50 } calculateArea(); // console.log(length); // ❌ ReferenceError — বাইরে দেখা যাচ্ছে না!

৩. Block Scope { } এর ভেতরে সীমাবদ্ধ

{ } দিয়ে ঘেরা যেকোনো অংশই Block। letconst Block-scoped — Block-এর বাইরে এদের দেখা যায় না।

// let — Block Scope if (true) { let blockLet = "আমি block-এ"; const blockConst = "আমিও block-এ"; console.log(blockLet); // → আমি block-এ ✅ } // console.log(blockLet); // ❌ ReferenceError — block-এর বাইরে নেই // var — Block Scope বোঝে না! if (true) { var blockVar = "আমি var"; } console.log(blockVar); // → আমি var ⚠️ (বাইরেও দেখা যাচ্ছে!)

Scope Chain — ভেতর থেকে বাইরে খোঁজা Scope Chain

ভেতরের Scope সবসময় বাইরের Scope-এর Variable খুঁজে পায়। কিন্তু বাইরের Scope ভেতরের Variable দেখতে পায় না।

let globalVar = "আমি Global"; function outer() { let outerVar = "আমি Outer"; function inner() { let innerVar = "আমি Inner"; // ভেতর থেকে বাইরের সব দেখা যাচ্ছে: console.log(innerVar); // → আমি Inner ✅ console.log(outerVar); // → আমি Outer ✅ console.log(globalVar); // → আমি Global ✅ } inner(); // console.log(innerVar); // ❌ Error — ভেতরের দেখা যাচ্ছে না } outer();

Scope তুলনা — এক নজরে Summary

Scope ধরন কোথায় দেখা যায়? কোন keyword?
Global Scope সর্বত্র — পুরো প্রোগ্রামে var, let, const
Function Scope শুধু সেই Function-এর ভেতরে var, let, const
Block Scope শুধু সেই { }-এর ভেতরে let, const (var নয়)

🔷 দ্রুত রেফারেন্স — JavaScript Variables

বিষয় তথ্য / Keyword উদাহরণ / নোট
পরিবর্তনযোগ্য Variable let let count = 0;
স্থায়ী Variable const const PI = 3.14;
পুরনো পদ্ধতি (এড়াও) var Function-scoped, সমস্যাজনক
টেক্সট String let name = "করিম";
সংখ্যা Number let age = 22;
সত্য / মিথ্যা Boolean let ok = true;
ইচ্ছাকৃত খালি null let val = null;
মান নেই undefined let x; → undefined
Type জানা typeof typeof "abc""string"
var Hoisting undefined সহ উপরে যায় আগে ব্যবহার করলে undefined পাবে
let/const Hoisting TDZ-এ থাকে আগে ব্যবহার করলে ReferenceError
Global Scope সর্বত্র দেখা যায় Function-এর বাইরে declare করা
Function Scope Function-এর ভেতরে সীমাবদ্ধ বাইরে access করলে Error
Block Scope { }-এর ভেতরে সীমাবদ্ধ শুধু letconst
Naming Style camelCase totalScore, isLoggedIn
Constant Style UPPER_CASE MAX_SIZE, API_URL

🧠 নিজেকে যাচাই করো

1. const ও let-এর পার্থক্য?

2. var কেন এড়ানো উচিত?

3. Template literal কী?

✏️ Task — এখন তুমি করো

const, let দিয়ে portfolio information store করো। Template literal দিয়ে introduce করো।

ধাপ 2🏗️ Real Project — Interactive Portfolio

Portfolio-এ variables দিয়ে তোমার তথ্য রাখো।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio-এর সব data variables-এ রাখো।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

🗂️ JavaScript Data Types — সম্পূর্ণ নোট

এই সেকশনে JavaScript-এর সব Data Type, Prototype, Prototypal Inheritance, Built-in Objects সহ প্রতিটি বিষয় বাংলায় উদাহরণসহ বিস্তারিত আলোচনা করা হয়েছে।


🔷 Data Types কী ও কেন প্রয়োজন?

Data Type হলো তথ্যের ধরন বা প্রকার — অর্থাৎ একটি Variable-এ কোন ধরনের তথ্য রাখা আছে তা বোঝানোর উপায়।

সহজ উদাহরণ — "ঢাকা" একটি লেখা, 42 একটি সংখ্যা, true একটি সত্য/মিথ্যা মান। কম্পিউটার এদের আলাদাভাবে মেমোরিতে রাখে এবং আলাদা নিয়মে কাজ করে।

কেন প্রয়োজন? কারণ

কারণ ব্যাখ্যা উদাহরণ
মেমোরি সাশ্রয় ধরন অনুযায়ী সঠিক পরিমাণ মেমোরি ব্যবহার হয় সংখ্যার জন্য লেখার মতো বেশি জায়গা লাগে না
সঠিক অপারেশন কোন ধরনে কী কাজ করা যাবে তা নির্ধারণ করে "৫" + ২ = "৫২" বনাম ৫ + ২ = ৭
Error ধরা ভুল type-এ কাজ করলে সতর্ক করে লেখার উপর গণিত করলে NaN আসে
কোড বোঝা সহজ কোড পড়লে বোঝা যায় কোথায় কী তথ্য রাখা let isActive = true — স্পষ্ট

JavaScript = Dynamically Typed Language বিশেষত্ব

JavaScript হলো Dynamically Typed — Variable declare করার সময় type বলতে হয় না, মান দিলেই JavaScript নিজে বুঝে নেয়।

// Java (Statically Typed) — type বলতে হয়: // int age = 22; // String name = "করিম"; // JavaScript (Dynamically Typed) — type বলতে হয় না: let age = 22; // JS বুঝল: Number let name = "করিম"; // JS বুঝল: String let ok = true; // JS বুঝল: Boolean // একই Variable-এ ভিন্ন type দেওয়া যায়: let data = 100; data = "এখন লেখা"; // বৈধ — কোনো error নেই data = false; // আবার পরিবর্তন — বৈধ

Data Types-এর দুটি বিভাগ শ্রেণিবিভাগ

বিভাগ ধরনগুলো বৈশিষ্ট্য কীভাবে সংরক্ষিত?
Primitive String, Number, Boolean, null, undefined, BigInt, Symbol একটিমাত্র সরল মান। Immutable (পরিবর্তন হয় না)। Stack-এ সরাসরি মান রাখে
Non-Primitive (Reference) Object, Array, Function একাধিক মান ধারণ করে। Mutable (পরিবর্তন করা যায়)। Heap-এ মান, Stack-এ শুধু address রাখে
// Primitive — copy করলে নতুন মান তৈরি হয় let a = 10; let b = a; // b-তে 10-এর copy গেল b = 20; console.log(a); // → 10 (a অপরিবর্তিত) console.log(b); // → 20 // Non-Primitive — copy করলে একই object-কে point করে let obj1 = { city: "ঢাকা" }; let obj2 = obj1; // obj2 একই object-কে দেখছে obj2.city = "সিলেট"; console.log(obj1.city); // → সিলেট ⚠️ (obj1-ও বদলে গেল!)
⚠️ গুরুত্বপূর্ণ: Non-Primitive type copy করলে নতুন মান তৈরি হয় না — দুটো Variable একই object-কে point করে। এটি JavaScript-এর একটি বড় ফাঁদ।

🔷 ১. String — টেক্সট বা লেখা

String হলো যেকোনো লেখা, শব্দ বা বাক্য। কোটেশন মার্কের মধ্যে রাখলে JavaScript সেটাকে String হিসেবে চেনে।

কোটেশন ধরন উদাহরণ বিশেষত্ব
Single Quote ' ' let city = 'ঢাকা'; সাধারণ ব্যবহার
Double Quote " " let name = "করিম"; সাধারণ ব্যবহার
Backtick ` ` let msg = `হ্যালো ${name}`; Template Literal — Variable ও expression ঢোকানো যায়
let firstName = "রাহেলা"; let lastName = 'বেগম'; let age = 25; // Template Literal — backtick দিয়ে let intro = `আমার নাম ${firstName} ${lastName}, বয়স ${age} বছর।`; console.log(intro); // → আমার নাম রাহেলা বেগম, বয়স 25 বছর। // Template Literal-এ expression লেখা যায়: let result = `৫ × ৬ = ${5 * 6}`; console.log(result); // → ৫ × ৬ = 30

Escape Characters বিশেষ চিহ্ন

let text1 = "সে বলল, \"হ্যালো!\""; // → সে বলল, "হ্যালো!" let text2 = 'It\'s okay'; // → It's okay let text3 = "প্রথম লাইন\nদ্বিতীয় লাইন"; // \n = নতুন লাইন let text4 = "নাম:\tকরিম"; // \t = Tab let text5 = "পিছনের \\ স্ল্যাশ"; // \\ = একটি backslash

গুরুত্বপূর্ণ String Methods Methods

Method কাজ উদাহরণ
.length String-এর দৈর্ঘ্য "ঢাকা".length → 4
.toUpperCase() সব বড় হাতে "hello".toUpperCase() → "HELLO"
.toLowerCase() সব ছোট হাতে "HELLO".toLowerCase() → "hello"
.trim() দুপাশের Space সরায় " হ্যালো ".trim() → "হ্যালো"
.includes(str) String আছে কিনা "বাংলাদেশ".includes("বাংলা") → true
.indexOf(str) কোন position-এ আছে "hello".indexOf("l") → 2
.slice(start, end) অংশ বের করা "বাংলাদেশ".slice(0, 5) → "বাংলা"
.replace(old, new) অংশ বদলানো "হ্যালো".replace("হ্যালো", "নমস্কার")
.split(sep) Array-এ ভাগ করা "ক,খ,গ".split(",") → ["ক","খ","গ"]
.startsWith(str) দিয়ে শুরু? "বাংলা".startsWith("বাং") → true
.endsWith(str) দিয়ে শেষ? "বাংলা".endsWith("লা") → true
.repeat(n) n বার পুনরাবৃত্তি "হা".repeat(3) → "হাহাহা"
.padStart(n, char) বাম দিকে পূরণ "5".padStart(3, "0") → "005"
[index] নির্দিষ্ট অক্ষর "hello"[1] → "e"
let sentence = " আমি JavaScript শিখছি "; console.log(sentence.trim()); // → "আমি JavaScript শিখছি" console.log(sentence.trim().length); // → 22 console.log(sentence.includes("Java")); // → true console.log(sentence.trim().split(" ")); // → ["আমি", "JavaScript", "শিখছি"] // Method Chaining — একের পর এক method লাগানো যায়: let result = " Hello World " .trim() .toLowerCase() .replace("world", "বাংলাদেশ"); console.log(result); // → "hello বাংলাদেশ"
String Immutable: String-এর method গুলো মূল String পরিবর্তন করে না, নতুন String ফেরত দেয়। তাই result সংরক্ষণ করতে হলে Variable-এ রাখতে হবে।
let clean = " হ্যালো ".trim(); — এভাবে result রাখো।

🔷 ২. Number — সংখ্যা

JavaScript-এ Number দিয়ে পূর্ণ সংখ্যা, দশমিক সংখ্যা এবং ঋণাত্মক সংখ্যা সব একই type-এ রাখা হয়।

let integer = 42; // পূর্ণ সংখ্যা let decimal = 3.1416; // দশমিক সংখ্যা let negative = -15; // ঋণাত্মক সংখ্যা let binary = 0b1010; // Binary (দশমিকে 10) let hex = 0xFF; // Hexadecimal (দশমিকে 255) let exp = 2.5e3; // Scientific (দশমিকে 2500)

বিশেষ Number মান Special Values

মান অর্থ কখন আসে? উদাহরণ
NaN Not a Number — বৈধ সংখ্যা নয় ভুল গণনায় "abc" * 2 → NaN
Infinity ধনাত্মক অনন্ত শূন্য দিয়ে ভাগ 1 / 0 → Infinity
-Infinity ঋণাত্মক অনন্ত ঋণাত্মক শূন্য দিয়ে ভাগ -1 / 0 → -Infinity
MAX_SAFE_INTEGER নিরাপদ সর্বোচ্চ পূর্ণ সংখ্যা 9007199254740991 পর্যন্ত Number.MAX_SAFE_INTEGER
console.log(10 / 0); // → Infinity console.log(-10 / 0); // → -Infinity console.log("abc" * 2); // → NaN console.log(0 / 0); // → NaN // NaN-এর মজার বৈশিষ্ট্য: console.log(NaN === NaN); // → false ⚠️ NaN নিজের সমান নয়! console.log(isNaN(NaN)); // → true ← এভাবে চেক করো
⚠️ NaN সম্পর্কে সতর্কতা: NaN === NaN সবসময় false দেয়! NaN চেক করতে সবসময় Number.isNaN() বা isNaN() ব্যবহার করো।

গুরুত্বপূর্ণ Number Methods ও Functions Methods

Method / Function কাজ উদাহরণ
.toFixed(n) n দশমিক ঘর রেখে String ফেরত (3.14159).toFixed(2) → "3.14"
Number(val) অন্য type-কে Number-এ রূপান্তর Number("42") → 42
parseInt(str) String থেকে পূর্ণ সংখ্যা parseInt("42.9px") → 42
parseFloat(str) String থেকে দশমিক সংখ্যা parseFloat("3.14abc") → 3.14
Number.isNaN(val) NaN কিনা নির্ভরযোগ্যভাবে চেক Number.isNaN(NaN) → true
Number.isFinite(val) সীমিত সংখ্যা কিনা Number.isFinite(Infinity) → false
Number.isInteger(val) পূর্ণ সংখ্যা কিনা Number.isInteger(4.5) → false
let price = 1234.5678; console.log(price.toFixed(2)); // → "1234.57" console.log(parseInt("50px")); // → 50 console.log(parseFloat("3.14abc")); // → 3.14 console.log(Number("")); // → 0 console.log(Number("abc")); // → NaN console.log(Number(true)); // → 1 console.log(Number(false)); // → 0 console.log(Number(null)); // → 0

🔷 ৩. Boolean — সত্য বা মিথ্যা

Boolean-এ শুধু দুটো মান থাকে — true (সত্য) বা false (মিথ্যা)। শর্ত পরীক্ষায় এটি সবচেয়ে বেশি ব্যবহৃত।

let isLoggedIn = true; let hasError = false; let isAdult = 18 >= 18; // → true let isEmpty = 0 === 0; // → true console.log(typeof isLoggedIn); // → "boolean" // if শর্তে Boolean: if (isLoggedIn) { console.log("স্বাগতম!"); // → স্বাগতম! } else { console.log("লগইন করো।"); }

Truthy ও Falsy — অত্যন্ত গুরুত্বপূর্ণ! ⭐ মুখস্থ করো

JavaScript-এ if() শর্তে Boolean ছাড়া অন্য মানও ব্যবহার করা যায়। কিছু মান false-এর মতো আচরণ করে — এদের Falsy বলে। বাকি সব মানকে Truthy বলে।

Falsy মান উদাহরণ if()-তে ফলাফল
false if (false) ❌ ঢোকে না
0 if (0) ❌ ঢোকে না
"" (খালি string) if ("") ❌ ঢোকে না
null if (null) ❌ ঢোকে না
undefined if (undefined) ❌ ঢোকে না
NaN if (NaN) ❌ ঢোকে না
// Falsy মান পরীক্ষা: if (0) { } else { console.log("0 = Falsy"); } // → 0 = Falsy if ("") { } else { console.log('"" = Falsy'); } // → "" = Falsy if (null) { } else { console.log("null = Falsy"); } // → null = Falsy if (undefined) { } else { console.log("undef = Falsy"); } // → undef = Falsy // Truthy মান পরীক্ষা: if ("0") { console.log('"0" = Truthy'); } // → "0" = Truthy (string!) if ([]) { console.log('[] = Truthy'); } // → [] = Truthy (খালি array!) if ({}) { console.log('{} = Truthy'); } // → {} = Truthy (খালি object!) if (-1) { console.log('-1 = Truthy'); } // → -1 = Truthy
মনে রাখো Falsy মানগুলো: false, 0, "", null, undefined, NaN — মাত্র এই ৬টি। বাকি সব Truthy — এমনকি "false" (string), [], {} সবই Truthy।

🔷 ৪. undefined — সংজ্ঞায়িত হয়নি

undefined মানে Variable তৈরি হয়েছে কিন্তু এখনো কোনো মান দেওয়া হয়নি। JavaScript নিজেই এই মান বসিয়ে দেয় — আমরা সাধারণত নিজে দিই না।

কোথায় কোথায় undefined আসে? কারণ

// ১. Variable declare করা হয়েছে কিন্তু মান নেই: let x; console.log(x); // → undefined // ২. Object-এ নেই এমন property access: let obj = { name: "করিম" }; console.log(obj.age); // → undefined // ৩. Function-এ return না থাকলে: function doNothing() { } let result = doNothing(); console.log(result); // → undefined // ৪. Array-এ নেই এমন index: let arr = [10, 20]; console.log(arr[5]); // → undefined // typeof undefined: console.log(typeof undefined); // → "undefined"
ভালো অভ্যাস: undefined নিজে assign করো না। Variable খালি রাখতে চাইলে null ব্যবহার করো।
let value = null; ← এভাবে করো, let value = undefined; নয়।

🔷 ৫. null — ইচ্ছাকৃত শূন্যতা

null মানে ইচ্ছাকৃতভাবে কিছু নেই — আমরা নিজে দিই বোঝাতে যে "এখানে এখনো কোনো মান নির্ধারণ করা হয়নি।"

let selectedUser = null; // এখনো কোনো user বাছাই হয়নি let currentOrder = null; // এখনো কোনো order নেই // পরে মান দেওয়া হবে: selectedUser = { id: 1, name: "করিম" }; console.log(selectedUser.name); // → করিম // null চেক: if (currentOrder === null) { console.log("কোনো order নেই।"); } // typeof null — একটি বিখ্যাত bug: console.log(typeof null); // → "object" ⚠️ (null কিন্তু object নয়!)

null vs undefined — পার্থক্য তুলনা

বিষয় null undefined
কে দেয়? প্রোগ্রামার নিজে JavaScript নিজে
অর্থ ইচ্ছাকৃত "কিছু নেই" মান দেওয়া হয়নি
typeof "object" ⚠️ (bug) "undefined"
Loose equality null == undefined → true null == undefined → true
Strict equality null === undefined → false null === undefined → false
console.log(null == undefined); // → true (loose — উভয়ই "নেই" বোঝায়) console.log(null === undefined); // → false (strict — type আলাদা)

🔷 ৬. BigInt — বিশাল সংখ্যা

JavaScript-এর সাধারণ Number type নিরাপদে সর্বোচ্চ 9,007,199,254,740,991 (2⁵³ - 1) পর্যন্ত পূর্ণ সংখ্যা রাখতে পারে। এর বেশি বড় সংখ্যার জন্য BigInt ব্যবহার হয়।

// Number-এর সীমা সমস্যা: console.log(Number.MAX_SAFE_INTEGER); // → 9007199254740991 console.log(9007199254740991 + 1); // → 9007199254740992 ✅ console.log(9007199254740991 + 2); // → 9007199254740992 ⚠️ (ভুল!) // BigInt — n লাগিয়ে তৈরি: let bigNum = 9007199254740991n; console.log(bigNum + 2n); // → 9007199254740993n ✅ (সঠিক!) // BigInt() function দিয়েও তৈরি করা যায়: let big = BigInt("12345678901234567890"); console.log(typeof bigNum); // → "bigint"
⚠️ BigInt-এর সীমাবদ্ধতা:
→ BigInt ও Number একসাথে গণনা করা যায় না — আগে convert করতে হবে।
BigInt + Number → TypeError
→ দশমিক সংখ্যা (float) BigInt-এ রাখা যায় না।
→ সাধারণ প্রোগ্রামিংয়ে BigInt বিরল — বিশেষ ক্ষেত্রে (ব্যাংক, ক্রিপ্টো) দরকার হয়।

🔷 ৭. Symbol — অনন্য পরিচয়

Symbol হলো ES6-এ আসা একটি অনন্য (unique) primitive type। প্রতিবার Symbol তৈরি করলে সেটি সম্পূর্ণ নতুন ও অনন্য — একই বর্ণনা দিলেও দুটো Symbol কখনো সমান হয় না।

let sym1 = Symbol("id"); let sym2 = Symbol("id"); console.log(sym1 === sym2); // → false (একই বর্ণনা, তবুও আলাদা!) console.log(typeof sym1); // → "symbol" console.log(sym1.toString()); // → "Symbol(id)" console.log(sym1.description); // → "id" // Object-এর unique key হিসেবে ব্যবহার: const USER_ID = Symbol("userId"); const user = { name: "করিম", [USER_ID]: 12345 // Symbol key — সহজে access বা override হয় না }; console.log(user[USER_ID]); // → 12345 console.log(user.userId); // → undefined (Symbol key সাধারণ dot notation-এ দেখা যায় না)
কখন Symbol ব্যবহার করবে? Library বা Framework তৈরিতে, অথবা যখন Object-এ এমন property রাখতে হবে যা অন্য কেউ override করতে পারবে না। সাধারণ প্রোগ্রামিংয়ে Symbol বিরল।

🔷 ৮. Object — জটিল তথ্য পাত্র

Object হলো Key-Value জোড়ায় একাধিক তথ্য একসাথে রাখার পাত্র। JavaScript-এ Object হলো সবচেয়ে শক্তিশালী এবং বহুল ব্যবহৃত data structure।

Object তৈরির উপায় Creation

// ১. Object Literal — সবচেয়ে সাধারণ পদ্ধতি const student = { name: "রাহেলা", age: 20, city: "চট্টগ্রাম", isActive: true }; // ২. new Object() — পুরনো পদ্ধতি (এড়িয়ে চলো) const car = new Object(); car.brand = "Toyota"; car.year = 2022; // ৩. Constructor Function (পরে বিস্তারিত) function Person(name, age) { this.name = name; this.age = age; } const p1 = new Person("করিম", 25);

Property Access — দুটি পদ্ধতি Access

const book = { title: "বাংলা সাহিত্য", pages: 350, price: 200 }; // ১. Dot Notation — সাধারণ ক্ষেত্রে console.log(book.title); // → বাংলা সাহিত্য console.log(book.pages); // → 350 // ২. Bracket Notation — key variable বা বিশেষ চিহ্ন থাকলে console.log(book["price"]); // → 200 let key = "title"; console.log(book[key]); // → বাংলা সাহিত্য (dynamic key) // নেই এমন property: console.log(book.author); // → undefined

Property যোগ, পরিবর্তন ও মুছে ফেলা CRUD

const product = { name: "চাল", price: 60 }; // পরিবর্তন: product.price = 65; console.log(product.price); // → 65 // নতুন property যোগ: product.quantity = 100; product.inStock = true; // মুছে ফেলা: delete product.quantity; console.log(product); // → { name: "চাল", price: 65, inStock: true }

Nested Object ও Method Advanced

const person = { name: "করিম", address: { // Nested Object city: "ঢাকা", area: "মিরপুর" }, hobbies: ["পড়া", "খেলা"], // Array inside Object greet: function() { // Method (Object-এর ভেতরের Function) console.log(`আমি ${this.name}, ${this.address.city} থেকে।`); } }; console.log(person.address.city); // → ঢাকা console.log(person.hobbies[0]); // → পড়া person.greet(); // → আমি করিম, ঢাকা থেকে।

গুরুত্বপূর্ণ Object Methods Built-in

Method কাজ উদাহরণ
Object.keys(obj) সব key-এর Array → ["name", "age"]
Object.values(obj) সব value-এর Array → ["করিম", 25]
Object.entries(obj) key-value জোড়ার Array → [["name","করিম"],["age",25]]
Object.assign(target, src) একটি object-এ অন্যটি merge Object কপি বা একত্র করতে
Object.freeze(obj) Object পরিবর্তন বন্ধ করে Immutable object তৈরি করতে
hasOwnProperty(key) নিজস্ব property আছে কিনা obj.hasOwnProperty("name")
const user = { name: "রাহেলা", age: 20, city: "ঢাকা" }; console.log(Object.keys(user)); // → ["name", "age", "city"] console.log(Object.values(user)); // → ["রাহেলা", 20, "ঢাকা"] // Object copy (Shallow): const copy = Object.assign({}, user); const copy2 = { ...user }; // Spread — আরও সহজ // Object.freeze — পরিবর্তন বন্ধ: const config = Object.freeze({ version: "1.0", debug: false }); config.version = "2.0"; // চুপচাপ ব্যর্থ হয় (strict mode-এ Error) console.log(config.version); // → "1.0" (পরিবর্তন হয়নি)

🔷 Prototype — প্রতিটি Object-এর অদৃশ্য অভিভাবক

JavaScript-এ প্রতিটি Object-এর একটি লুকানো সংযোগ থাকে আরেকটি Object-এর সাথে — এটাই সেই Object-এর Prototype। কোনো property খুঁজে না পেলে JavaScript স্বয়ংক্রিয়ভাবে Prototype-এ গিয়ে খোঁজে।

সহজ উপমা: একটি পরিবারে সন্তান যদি কোনো দক্ষতা না জানে, তাহলে বাবা-মায়ের কাছ থেকে শেখে। বাবা না জানলে দাদার কাছে যায়। এই chain-ই JavaScript-এর Prototype Chain।

Prototype Chain কীভাবে কাজ করে? Chain

const animal = { breathe() { console.log("শ্বাস নিচ্ছে..."); } }; const dog = { bark() { console.log("ঘেউ ঘেউ!"); } }; // dog-এর prototype হিসেবে animal সেট করা: Object.setPrototypeOf(dog, animal); dog.bark(); // → ঘেউ ঘেউ! (নিজেরই method) dog.breathe(); // → শ্বাস নিচ্ছে... ✅ (prototype থেকে পেল!) // চেক করা: console.log(Object.getPrototypeOf(dog) === animal); // → true

Prototype Chain-এর শেষ Root

const obj = { x: 1 }; // Prototype Chain: // obj → Object.prototype → null // Object.prototype-এর method সব object ব্যবহার করতে পারে: console.log(obj.toString()); // → "[object Object]" (Object.prototype থেকে) console.log(obj.hasOwnProperty("x")); // → true (Object.prototype থেকে) // Chain-এর শেষ: console.log(Object.getPrototypeOf(Object.prototype)); // → null

Array ও Function-ও Object সব Object

// Array-এর Prototype Chain: // [] → Array.prototype → Object.prototype → null const arr = [1, 2, 3]; console.log(arr.push); // Array.prototype-এর method console.log(arr.toString); // Object.prototype-এর method // Function-এর Prototype Chain: // fn → Function.prototype → Object.prototype → null function greet() {} console.log(greet.call); // Function.prototype-এর method

🔷 Prototypal Inheritance — উত্তরাধিকার

Prototypal Inheritance মানে একটি Object আরেকটি Object-এর properties ও methods উত্তরাধিকার সূত্রে পেতে পারে — কোড পুনরায় লিখতে হয় না।

পদ্ধতি ১ — Object.create() সরাসরি

// Parent Object: const vehicle = { type: "যানবাহন", move() { console.log(`${this.name} চলছে...`); } }; // Child Object — vehicle থেকে inherit করছে: const bicycle = Object.create(vehicle); bicycle.name = "সাইকেল"; bicycle.wheels = 2; bicycle.move(); // → সাইকেল চলছে... (parent থেকে পেয়েছে) console.log(bicycle.type); // → যানবাহন (parent থেকে পেয়েছে) console.log(bicycle.wheels); // → 2 (নিজের property)

পদ্ধতি ২ — Constructor Function + .prototype Classical

// Constructor Function (প্রথম অক্ষর বড় হাতে — convention): function Animal(name, sound) { this.name = name; this.sound = sound; } // prototype-এ method রাখা — সব instance share করে: Animal.prototype.speak = function() { console.log(`${this.name} বলে: ${this.sound}`); }; // new দিয়ে instance তৈরি: const cat = new Animal("বিড়াল", "মিউ মিউ"); const cow = new Animal("গরু", "হাম্বা"); cat.speak(); // → বিড়াল বলে: মিউ মিউ cow.speak(); // → গরু বলে: হাম্বা // উভয়ই একই speak method share করছে: console.log(cat.speak === cow.speak); // → true (একই reference)

পদ্ধতি ৩ — ES6 class (Syntactic Sugar) আধুনিক পদ্ধতি

ES6-এর class হলো Constructor Function ও Prototype-এর সুন্দর লেখার পদ্ধতি — পেছনে একই Prototype-ভিত্তিক কাজ হয়।

// Parent Class: class Shape { constructor(color) { this.color = color; } describe() { console.log(`এটি একটি ${this.color} রঙের আকৃতি।`); } } // Child Class — extends দিয়ে inherit: class Circle extends Shape { constructor(color, radius) { super(color); // Parent-এর constructor ডাকা this.radius = radius; } area() { return Math.PI * this.radius ** 2; } } const c = new Circle("লাল", 5); c.describe(); // → এটি একটি লাল রঙের আকৃতি। (parent থেকে) console.log(c.area().toFixed(2)); // → 78.54 (নিজের method) // instanceof: console.log(c instanceof Circle); // → true console.log(c instanceof Shape); // → true (inheritance-এর কারণে)
class ব্যবহার করো — এটি সবচেয়ে পরিষ্কার ও আধুনিক। তবে মনে রেখো: class আসলে Prototype-ভিত্তিক Inheritance-এরই সুন্দর রূপ — JavaScript-এ Class-based Inheritance নেই।

🔷 typeof Operator — Data Type জানার উপায়

typeof operator যেকোনো মান বা Variable-এর Data Type কী তা String হিসেবে ফেরত দেয়।

console.log(typeof "হ্যালো"); // → "string" console.log(typeof 42); // → "number" console.log(typeof 3.14); // → "number" console.log(typeof true); // → "boolean" console.log(typeof undefined); // → "undefined" console.log(typeof null); // → "object" ⚠️ (bug!) console.log(typeof {}); // → "object" console.log(typeof []); // → "object" ⚠️ (array-ও object) console.log(typeof function(){}); // → "function" console.log(typeof Symbol()); // → "symbol" console.log(typeof 42n); // → "bigint"

typeof সম্পূর্ণ ফলাফল টেবিল Reference

মান typeof ফলাফল নোট
"লেখা" "string"
42, 3.14, NaN, Infinity "number" NaN ও Infinity-ও Number!
true, false "boolean"
undefined "undefined"
null "object" ⚠️ ঐতিহাসিক bug!
{}, new Date() "object"
[] "object" ⚠️ Array-ও "object"!
function(){} "function" Function একটি object, কিন্তু typeof "function" দেয়
Symbol() "symbol"
42n "bigint"

Array ও null সঠিকভাবে চেক করা সঠিক পদ্ধতি

// Array চেক — typeof কাজ করে না: let arr = [1, 2, 3]; console.log(typeof arr); // → "object" ← ভুল মনে হচ্ছে console.log(Array.isArray(arr)); // → true ✅ এটাই সঠিক // null চেক — typeof কাজ করে না: let val = null; console.log(typeof val); // → "object" ← ভুল মনে হচ্ছে console.log(val === null); // → true ✅ এটাই সঠিক

🔷 Built-in Objects — JavaScript-এর তৈরি বস্তু

JavaScript নিজেই কিছু Object তৈরি করে দিয়ে রেখেছে যা ব্যবহারের জন্য import করতে হয় না — সরাসরি ব্যবহার করা যায়।

১. Math Object — গণিতের হাতিয়ার Math

Property / Method কাজ উদাহরণ
Math.PI π এর মান → 3.141592653589793
Math.round(n) নিকটতম পূর্ণ সংখ্যায় Math.round(4.6) → 5
Math.floor(n) নিচের পূর্ণ সংখ্যায় Math.floor(4.9) → 4
Math.ceil(n) উপরের পূর্ণ সংখ্যায় Math.ceil(4.1) → 5
Math.abs(n) পরম মান (সর্বদা ধনাত্মক) Math.abs(-7) → 7
Math.max(...n) সর্বোচ্চ মান Math.max(3,9,1) → 9
Math.min(...n) সর্বনিম্ন মান Math.min(3,9,1) → 1
Math.pow(base, exp) ঘাত (power) Math.pow(2,10) → 1024
Math.sqrt(n) বর্গমূল Math.sqrt(25) → 5
Math.random() 0 থেকে 1-এর মধ্যে random Math.random() → 0.472...
// ১ থেকে ১০-এর মধ্যে Random সংখ্যা: let rand = Math.floor(Math.random() * 10) + 1; console.log(rand); // → 1 থেকে 10-এর মধ্যে যেকোনো একটি // বৃত্তের ক্ষেত্রফল: let radius = 7; let area = Math.PI * Math.pow(radius, 2); console.log(area.toFixed(2)); // → 153.94

২. Date Object — তারিখ ও সময় Date

// বর্তমান তারিখ ও সময়: const now = new Date(); console.log(now); // → বর্তমান date ও time console.log(now.getFullYear()); // → ২০২৫ (বছর) console.log(now.getMonth()); // → 0-11 (0 = জানুয়ারি) console.log(now.getDate()); // → মাসের দিন (1-31) console.log(now.getDay()); // → সপ্তাহের দিন (0=রবি, 6=শনি) console.log(now.getHours()); // → ঘণ্টা (0-23) console.log(now.getMinutes()); // → মিনিট // নির্দিষ্ট তারিখ তৈরি: const birthday = new Date(2000, 5, 15); // 2000 সালের জুন মাসের 15 তারিখ console.log(birthday.toLocaleDateString("bn-BD")); // বাংলা format-এ

৩. Array — তালিকা Array

Method কাজ উদাহরণ
.push(item) শেষে যোগ [1,2].push(3) → [1,2,3]
.pop() শেষেরটা সরায় [1,2,3].pop() → [1,2]
.unshift(item) শুরুতে যোগ [1,2].unshift(0) → [0,1,2]
.shift() শুরুরটা সরায় [1,2,3].shift() → [2,3]
.map(fn) প্রতিটিতে function চালায় [1,2].map(x => x*2) → [2,4]
.filter(fn) শর্তপূরণকারী রাখে [1,2,3].filter(x => x>1) → [2,3]
.find(fn) প্রথম মিল খোঁজে [1,2,3].find(x => x>1) → 2
.includes(item) আছে কিনা [1,2,3].includes(2) → true
.join(sep) String-এ পরিণত ["ক","খ"].join("-") → "ক-খ"
.sort() সাজানো [3,1,2].sort() → [1,2,3]
.slice(s, e) অংশ বের করা [1,2,3,4].slice(1,3) → [2,3]
.forEach(fn) প্রতিটিতে function চালায় কোনো নতুন array ফেরত দেয় না

৪. JSON Object — তথ্য আদান-প্রদান JSON

JSON (JavaScript Object Notation) হলো ডেটা আদান-প্রদানের সবচেয়ে জনপ্রিয় format। API থেকে ডেটা সাধারণত JSON-এ আসে।

// Object → JSON String (পাঠানোর জন্য): const user = { name: "করিম", age: 25, city: "ঢাকা" }; const jsonString = JSON.stringify(user); console.log(jsonString); // → '{"name":"করিম","age":25,"city":"ঢাকা"}' console.log(typeof jsonString); // → "string" // JSON String → Object (পাওয়ার পর): const received = '{"name":"রাহেলা","score":95}'; const obj = JSON.parse(received); console.log(obj.name); // → রাহেলা console.log(obj.score); // → 95 // সুন্দর করে দেখাতে: console.log(JSON.stringify(user, null, 2)); // → { // "name": "করিম", // "age": 25, // "city": "ঢাকা" // }

🔷 Type Coercion — স্বয়ংক্রিয় Type রূপান্তর

Type Coercion মানে JavaScript স্বয়ংক্রিয়ভাবে এক type-এর মানকে অন্য type-এ রূপান্তর করে — এটি অনেক সময় বিভ্রান্তিকর ফলাফল দেয়।

Implicit Coercion — JS নিজে করে সাবধান!

// + অপারেটর: Number + String = String (Concatenation) console.log(5 + "3"); // → "53" ⚠️ (সংখ্যা নয়!) console.log("5" + 3); // → "53" ⚠️ // - * / অপারেটর: String → Number-এ রূপান্তর হয় console.log("10" - 4); // → 6 ✅ (কাজ করেছে) console.log("6" * "2"); // → 12 ✅ console.log("abc" - 1); // → NaN ⚠️ // Comparison: console.log("5" == 5); // → true ⚠️ (type ignore করে তুলনা) console.log("5" === 5); // → false ✅ (type সহ কঠিন তুলনা) console.log(null == undefined); // → true (loose equality) console.log(false == 0); // → true ⚠️ console.log("" == false); // → true ⚠️
⚠️ == এড়িয়ে চলো: Loose equality (==) type ignore করে তুলনা করে, অনেক বিভ্রান্তিকর ফলাফল দেয়। সবসময় === (strict equality) ব্যবহার করো।

Explicit Conversion — আমরা নিজে করি নিরাপদ

রূপান্তর পদ্ধতি উদাহরণ
যেকোনো → Number Number(), parseInt(), parseFloat() Number("42") → 42
যেকোনো → String String(), .toString() String(100) → "100"
যেকোনো → Boolean Boolean() Boolean(0) → false
// String → Number: console.log(Number("42")); // → 42 console.log(Number("")); // → 0 console.log(Number("abc")); // → NaN console.log(Number(true)); // → 1 console.log(Number(false)); // → 0 console.log(Number(null)); // → 0 // Number → String: console.log(String(42)); // → "42" console.log((42).toString()); // → "42" console.log(42 + ""); // → "42" (implicit — এড়িয়ে চলো) // যেকোনো → Boolean: console.log(Boolean(1)); // → true console.log(Boolean(0)); // → false console.log(Boolean("a")); // → true console.log(Boolean("")); // → false

🔷 দ্রুত রেফারেন্স — JavaScript Data Types

Data Type typeof ফলাফল উদাহরণ মান বিশেষ নোট
String "string" "হ্যালো", 'ঢাকা' Immutable। Template literal-এ ${} ব্যবহার করো।
Number "number" 42, 3.14, NaN NaN ও Infinity-ও Number। ===-এ NaN চেক হয় না।
Boolean "boolean" true, false Falsy: false, 0, "", null, undefined, NaN
undefined "undefined" undefined JS নিজে দেয়। নিজে দিও না।
null "object" ⚠️ null ইচ্ছাকৃত শূন্যতা। চেক করতে === null ব্যবহার করো।
BigInt "bigint" 42n সংখ্যার শেষে n। Number-এর সাথে mix করা যায় না।
Symbol "symbol" Symbol("id") সর্বদা unique। Object-এর private key হিসেবে ব্যবহার।
Object "object" { key: value } Reference type। Copy করলে একই object point করে।
Array "object" ⚠️ [1, 2, 3] Array চেক করতে Array.isArray() ব্যবহার করো।
Function "function" function(){} Function-ও আসলে Object।

গুরুত্বপূর্ণ বিষয় একনজরে Summary

বিষয় সঠিক পদ্ধতি
Array চেক Array.isArray(arr)
null চেক val === null
NaN চেক Number.isNaN(val)
Strict তুলনা === ব্যবহার করো, == নয়
Object copy { ...obj } বা Object.assign({}, obj)
Prototype-ভিত্তিক Inheritance class + extends ব্যবহার করো
Type রূপান্তর Number(), String(), Boolean() ব্যবহার করো
Object ↔ JSON JSON.stringify() / JSON.parse()

🧠 নিজেকে যাচাই করো

1. typeof null?

2. JavaScript-এ কতটি primitive type?

3. Array কোন type?

✏️ Task — এখন তুমি করো

typeof operator দিয়ে বিভিন্ন value-এর type check করো। console-এ দেখো।

ধাপ 3🏗️ Real Project — Interactive Portfolio

বিভিন্ন data type দিয়ে portfolio information store করো।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio data-এর প্রতিটি property-এর type console-এ দেখো।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

🔄 JavaScript Type Casting — সম্পূর্ণ নোট

এই সেকশনে JavaScript-এ Type Casting কী, Implicit ও Explicit Casting-এর পার্থক্য, String/Number/Boolean রূপান্তর এবং সাধারণ ভুলগুলো বাংলায় বিস্তারিত আলোচনা করা হয়েছে।


🔷 Type Casting কী ও কেন প্রয়োজন?

Type Casting (বা Type Conversion) মানে এক Data Type-এর মানকে অন্য Data Type-এ রূপান্তর করা। যেমন "42" (String) কে 42 (Number)-এ রূপান্তর।

সহজ উদাহরণ — ব্যবহারকারী ফর্মে বয়স লিখলে সেটা সবসময় String হিসেবে আসে। কিন্তু গণনা করতে হলে সেটাকে Number-এ রূপান্তর করতে হয়।

// ফর্ম থেকে আসা মান সবসময় String: let ageFromForm = "22"; // String let nextYear = ageFromForm + 1; console.log(nextYear); // → "221" ⚠️ (গণনা হয়নি!) // Type Casting করার পর: let ageNumber = Number(ageFromForm); // String → Number let correct = ageNumber + 1; console.log(correct); // → 23 ✅

কখন Type Casting দরকার হয়? Use Cases

পরিস্থিতি সমস্যা সমাধান
HTML Form Input ইনপুট সবসময় String হিসেবে আসে Number() দিয়ে রূপান্তর
API Response JSON-এ সংখ্যা String হতে পারে parseInt() / parseFloat()
Display করা Number-কে পেজে দেখাতে String লাগে String() বা .toString()
Condition চেক কোনো মান আছে কিনা নিশ্চিত করা Boolean() বা !!
URL Parameter URL-এ সব মান String parseInt() দিয়ে রূপান্তর

দুই ধরনের Type Casting প্রকারভেদ

ধরন কে করে? উদাহরণ নিরাপদ?
Implicit Casting
(Type Coercion)
JavaScript নিজে স্বয়ংক্রিয়ভাবে "5" + 3 → "53" ⚠️ বিপজ্জনক
Explicit Casting
(Type Conversion)
প্রোগ্রামার নিজে জেনেশুনে করে Number("5") + 3 → 8 ✅ নিরাপদ

🔷 Type Conversion VS Type Coercion — বিস্তারিত পরিচয়

Type Conversion এবং Type Coercion — দুটো শব্দ একই কাজ (type পরিবর্তন) বোঝায়, কিন্তু কে করছে তাতে পার্থক্য। JavaScript- এ এই দুটো ভিন্ন অর্থে ব্যবহার হয়।

মূল পার্থক্য Definition

বিষয় Type Conversion (Explicit) Type Coercion (Implicit)
কে করে? প্রোগ্রামার নিজে JavaScript Engine নিজে
কীভাবে? Explicit function/method ডেকে Operator বা Context দেখে স্বয়ংক্রিয়ভাবে
নিয়ন্ত্রণ ✅ সম্পূর্ণ নিয়ন্ত্রণে ⚠️ JavaScript নিজেই সিদ্ধান্ত নেয়
নির্ভরযোগ্যতা ✅ পূর্বানুমানযোগ্য ফলাফল ⚠️ অপ্রত্যাশিত ফলাফল হতে পারে
উদাহরণ Number("5") "5" - 0
ব্যবহার করা উচিত? ✅ সবসময় পছন্দনীয় ❌ সাধারণত এড়িয়ে চলো

একই কাজ — দুই পদ্ধতিতে তুলনা

// ════════════════════════════════════════ // String → Number // ════════════════════════════════════════ // Coercion (Implicit) — JS নিজে করে: let a = "10" - 0; // → 10 (- operator JS-কে "10" → 10 করায়) let b = "10" * 1; // → 10 (একই কাজ ভিন্নভাবে) let c = +"10"; // → 10 (Unary plus) // Conversion (Explicit) — আমরা করি: let d = Number("10"); // → 10 ✅ পরিষ্কার ও নিরাপদ let e = parseInt("10", 10);// → 10 ✅ // ════════════════════════════════════════ // Number → String // ════════════════════════════════════════ // Coercion (Implicit): let f = 42 + ""; // → "42" ⚠️ (+ String থাকায় concat হলো) // Conversion (Explicit): let g = String(42); // → "42" ✅ let h = (42).toString(); // → "42" ✅ // ════════════════════════════════════════ // যেকোনো → Boolean // ════════════════════════════════════════ // Coercion (Implicit): if ("hello") { /* truthy */ } // JS নিজেই "hello" → true করে let i = !!"hello"; // → true (double negation) // Conversion (Explicit): let j = Boolean("hello"); // → true ✅ পরিষ্কার

JavaScript কোথায় কোথায় Coercion করে? Coercion ঘটার জায়গা

কোথায়? কীভাবে Coercion হয়? উদাহরণ
+ Operator যেকোনো একটি String হলে সব String-এ 1 + "2" → "12"
- * / % Operator String থাকলে Number-এ রূপান্তর "6" / "2" → 3
== Comparison ভিন্ন type হলে Coercion করে তুলনা 0 == false → true
if() / while() যেকোনো মান → Boolean-এ if("") → false
Template Literal সব মান → String-এ `${42}` → "42"
Logical Operator || &&-এ Truthy/Falsy চেক "" || "default" → "default"

JavaScript-এর বিখ্যাত অদ্ভুত Coercion 🤯 অবাক করা

// এগুলো সবই JavaScript-এর বৈধ Coercion: console.log([] + []); // → "" (দুটো array → String) console.log([] + {}); // → "[object Object]" console.log({} + []); // → 0 (context ভিন্ন!) console.log(+""); // → 0 console.log(+[]); // → 0 console.log(+{}); // → NaN console.log(!![]); // → true (খালি array Truthy!) console.log([] == false); // → true ⚠️ ([] → "" → 0 == false → 0) console.log([] == ![]); // → true ⚠️ (এটা বিখ্যাত!) console.log(null + 1); // → 1 console.log(null + null); // → 0 console.log(undefined + null); // → NaN
⚠️ এই অদ্ভুত আচরণগুলোই কারণ কেন Implicit Coercion এড়িয়ে সবসময় Explicit Conversion ব্যবহার করা উচিত। [] == false বা [] == ![] — এগুলো বাস্তব কোডে ধরা কঠিন bug তৈরি করে।

সংক্ষিপ্ত সারাংশ Summary

লক্ষ্য Coercion (এড়িয়ে চলো) ⚠️ Conversion (ব্যবহার করো) ✅
→ Number "5" - 0 বা +"5" Number("5") বা parseInt("5", 10)
→ String 5 + "" String(5) বা (5).toString()
→ Boolean !!val (অনেকে ব্যবহার করেন) Boolean(val)
তুলনা == (Loose) === (Strict)
মূল কথা:
Type Coercion = JavaScript চুপচাপ নিজেই করে — অনেক সময় ভুল ফলাফল।
Type Conversion = তুমি নিজে জেনেশুনে করো — নিরাপদ ও পূর্বানুমানযোগ্য।
→ পেশাদার কোডে সবসময় Explicit Conversion ব্যবহার করো।

🔷 Type Coercion — বিস্তারিত (Implicit)

Type Coercion হলো JavaScript-এর এমন একটি আচরণ যেখানে কোনো operator বা expression-এ ভিন্ন type-এর মান ব্যবহার হলে JavaScript Engine নিজেই একটিকে রূপান্তর করে নেয় — প্রোগ্রামার না জানলেও।

১. String Coercion — কখন ও কীভাবে? String Context

নিচের পরিস্থিতিতে JavaScript মানকে String-এ Coerce করে:

পরিস্থিতি উদাহরণ কী হয়?
+ operator-এ একটি String "বয়স: " + 22 22"22", ফলে "বয়স: 22"
Template Literal ${} `মান: ${true}` true"true"
String() function (Explicit) String(null) null"null"
// + operator — String থাকলে সব String-এ পরিণত: console.log("নম্বর: " + 42); // → "নম্বর: 42" console.log("মান: " + true); // → "মান: true" console.log("ফল: " + null); // → "ফল: null" console.log("ফল: " + undefined); // → "ফল: undefined" console.log("ফল: " + [1, 2, 3]); // → "ফল: 1,2,3" console.log("ফল: " + {}); // → "ফল: [object Object]" // ক্রম গুরুত্বপূর্ণ — বাম থেকে ডানে: console.log(1 + 2 + "3"); // → "33" (1+2=3, তারপর 3+"3"="33") console.log("1" + 2 + 3); // → "123" ("1"+2="12", "12"+3="123") console.log(1 + "2" + 3); // → "123" (1+"2"="12", "12"+3="123") // Template Literal — সব মান String-এ: let score = 95; let pass = true; console.log(`স্কোর ${score}, পাস: ${pass}`); // → "স্কোর 95, পাস: true"

২. Number Coercion — কখন ও কীভাবে? Number Context

নিচের পরিস্থিতিতে JavaScript মানকে Number-এ Coerce করে:

Operator / Context উদাহরণ Coercion নিয়ম
Arithmetic - * / % ** "10" * 2 "10"10, ফলে 20
Unary +- +"42" "42"42
Comparison < > <= >= "5" > 3 "5"5, ফলে true
Bitwise | & ^ "7" | 0 "7"7, ফলে 7
// Arithmetic — String → Number: console.log("10" - 3); // → 7 ("10"→10, 10-3=7) console.log("8" * "2"); // → 16 console.log("20" / "4"); // → 5 console.log("10" % "3"); // → 1 console.log("2" ** "3"); // → 8 (2³) // Number Coercion-এর নিয়ম বিভিন্ন মানে: console.log("5" - true); // → 4 (true→1, "5"→5, 5-1=4) console.log("5" - false); // → 5 (false→0) console.log("5" - null); // → 5 (null→0) console.log("5" - undefined); // → NaN (undefined→NaN) console.log(null - null); // → 0 console.log(true - false); // → 1 // সংখ্যা হওয়া সম্ভব না → NaN: console.log("abc" * 2); // → NaN console.log("10abc" - 1); // → NaN (Number("10abc")=NaN) // Comparison Coercion: console.log("10" > 9); // → true ("10"→10, 10>9) console.log("10" > "9"); // → false ⚠️ (String তুলনা! "1"<"9") console.log("10">= 10); // → true // Bitwise: console.log(3.9 | 0); // → 3 (দশমিক কেটে integer করার trick) console.log("7.8" | 0); // → 7
⚠️ String Comparison সাবধান: "10" > "9"false কারণ উভয়ই String হলে character-by-character তুলনা হয় — "1" < "9"। Number-এর সাথে তুলনায় Number Coercion হয়।

৩. Boolean Coercion — কখন ও কীভাবে? Boolean Context

নিচের context-এ JavaScript মানকে Boolean-এ Coerce করে:

// if() / else if() / while() — সব মান Boolean-এ: if (1) { console.log("1 = Truthy"); } if ("hello") { console.log('"hello" = Truthy'); } if ([]) { console.log("[] = Truthy"); } // ⚠️ খালি array Truthy! if (0) { /* চলবে না */ } else { console.log("0 = Falsy"); } if ("") { /* চলবে না */ } else { console.log('"" = Falsy'); } if (null) { /* চলবে না */ } else { console.log("null = Falsy"); } // Ternary — condition Boolean-এ: let score = 75; let result = score >= 50 ? "পাস" : "ফেল"; // 75>=50=true → "পাস" console.log(result); // → পাস // Logical Operators — Boolean Context-এ চলে: // || = প্রথম Truthy মান ফেরত দেয়: console.log(0 || "default"); // → "default" (0 Falsy, তাই পরের টা) console.log("hello" || "world"); // → "hello" (প্রথমটাই Truthy) console.log(null || undefined); // → undefined (উভয়ই Falsy, শেষটা) // && = প্রথম Falsy মান ফেরত দেয়: console.log(1 && 2 && 3); // → 3 (সব Truthy, শেষটা) console.log(1 && 0 && 3); // → 0 (0 Falsy, সেটাই ফেরত) console.log("" && "hello"); // → "" ("" Falsy) // ! (Negation) — Boolean-এ করে উল্টায়: console.log(!0); // → true (0 Falsy → true) console.log(!"hello"); // → false ("hello" Truthy → false) console.log(!null); // → true console.log(!![]); // → true ([] Truthy)
Logical Operator-এর practical ব্যবহার:
let name = userInput || "অতিথি";userInput falsy (খালি বা null) হলে "অতিথি" default হিসেবে ব্যবহার হবে।

isLoggedIn && showDashboard();isLoggedIn true হলেই showDashboard() চলবে।

৪. Abstract Equality (==) — Coercion-এর নিয়ম == এর রহস্য

== (Loose Equality) অপারেটর নির্দিষ্ট নিয়মে Coercion করে তুলনা করে। নিয়মগুলো জানলে অদ্ভুত ফলাফলগুলো বোঝা যায়:

তুলনা Coercion নিয়ম ফলাফল
null == undefined বিশেষ নিয়ম — শুধু এরা পরস্পর equal true
null == 0 null শুধু undefined-এর সাথে == false
"5" == 5 String → Number: "5"→5 true
true == 1 Boolean → Number: true→1 true
false == 0 Boolean → Number: false→0 true
false == "" false→0, ""→0 true
[] == false false→0, []→""→0 true
[] == ![] ![]→false→0, []→""→0 true 🤯
"0" == false false→0, "0"→0 true
// == Coercion ধাপে ধাপে বোঝো: // "5" == 5 // → String vs Number → "5" কে Number করো → Number("5")=5 // → 5 == 5 → true // false == "" // → Boolean vs String → false কে Number করো → 0 // → 0 == "" → String vs Number → Number("")=0 // → 0 == 0 → true // [] == false // → Boolean vs Object → false কে Number করো → 0 // → [] == 0 → Object vs Number → [].valueOf()=[], [].toString()="" // → "" == 0 → Number("")=0 // → 0 == 0 → true 🤯 // null এর বিশেষ আচরণ: console.log(null == undefined); // → true (বিশেষ নিয়ম) console.log(null == 0); // → false (null শুধু undefined-এর সাথে) console.log(null == false); // → false console.log(null == ""); // → false console.log(null == null); // → true
⚠️ কেন === ব্যবহার করবে: ==-এর Coercion নিয়ম মনে রাখা কঠিন এবং অনেক সময় অপ্রত্যাশিত bug তৈরি করে। === (Strict Equality) কোনো Coercion করে না — type ও মান উভয়ই মিললে তবেই true

🔷 Type Conversion — বিস্তারিত (Explicit)

Type Conversion মানে প্রোগ্রামার নিজে সচেতনভাবে কোনো মানকে ভিন্ন type-এ রূপান্তর করে। এটি সবসময় পূর্বানুমানযোগ্য ও নিরাপদ।

String Conversion — বিস্তারিত নিয়ম → String

মূল মান Type String() ফলাফল ব্যাখ্যা
0 Number "0"
-0 Number "0" ⚠️ -0 কিন্তু "0" দেখায়
NaN Number "NaN"
Infinity Number "Infinity"
-Infinity Number "-Infinity"
true Boolean "true"
false Boolean "false"
null null "null" .toString()-এ Error!
undefined undefined "undefined" .toString()-এ Error!
[] Array "" খালি array = খালি string
[1,2,3] Array "1,2,3" comma দিয়ে জোড়া
{} Object "[object Object]" সব plain object
function(){} Function "function(){}" Function-এর source code
// String() — সব মান handle করে, নিরাপদ: console.log(String(0)); // → "0" console.log(String(-0)); // → "0" ⚠️ (মনে রাখো) console.log(String(NaN)); // → "NaN" console.log(String(null)); // → "null" ✅ console.log(String(undefined)); // → "undefined" ✅ // .toString() — null/undefined-এ Error: console.log((42).toString()); // → "42" console.log((255).toString(2)); // → "11111111" (Binary) console.log((255).toString(16)); // → "ff" (Hex) // null.toString() → TypeError! ❌ // undefined.toString() → TypeError! ❌ // তিন পদ্ধতির পার্থক্য: let n = 42; console.log(String(n)); // → "42" ✅ সবচেয়ে নিরাপদ console.log(n.toString()); // → "42" ✅ radix দিতে পারবে console.log(`${n}`); // → "42" ✅ সহজ

Number Conversion — বিস্তারিত নিয়ম → Number

মূল মান Type Number() parseInt() parseFloat()
"42" String 42 42 42
"3.14" String 3.14 3 ✂️ 3.14
"42px" String NaN ⚠️ 42 42
"px42" String NaN NaN NaN
"" String 0 ⚠️ NaN NaN
" 42 " String 42 (space ছাঁটে) 42 42
true Boolean 1 NaN NaN
false Boolean 0 NaN NaN
null null 0 NaN NaN
undefined undefined NaN NaN NaN
[] Array 0 NaN NaN
[5] Array 5 NaN NaN
[1,2] Array NaN NaN NaN
{} Object NaN NaN NaN
// Number() — সম্পূর্ণ রূপান্তরের চেষ্টা করে: console.log(Number(" 100 ")); // → 100 (whitespace ছাঁটে) console.log(Number("0x1F")); // → 31 (hex string বোঝে) console.log(Number("0b101")); // → 5 (binary string বোঝে) console.log(Number("0o17")); // → 15 (octal string বোঝে) console.log(Number("1_000")); // → NaN (underscore separator বোঝে না) // parseInt(str, radix) — শুরু থেকে পড়ে, প্রথম বাধায় থামে: console.log(parseInt("42.9abc", 10)); // → 42 (. এ থামে) console.log(parseInt("3.9", 10)); // → 3 (দশমিক কাটে) console.log(parseInt("0xff", 16)); // → 255 console.log(parseInt("11", 2)); // → 3 (binary 11 = decimal 3) console.log(parseInt(" -42", 10)); // → -42 (sign ও space handle করে) // parseFloat — দশমিক সংখ্যার জন্য: console.log(parseFloat("3.14xyz")); // → 3.14 console.log(parseFloat("3.14.99")); // → 3.14 (দ্বিতীয় . বাদ) console.log(parseFloat(".5")); // → 0.5

Boolean Conversion — বিস্তারিত নিয়ম → Boolean

মান Boolean() মনে রাখার উপায়
false false নিজেই false
0, -0, +0 false সব শূন্য false
0n false BigInt শূন্য
"" / '' / `` false খালি string
null false "কিছু নেই"
undefined false "মান নেই"
NaN false "সংখ্যা নয়"
বাকি সব মান true "০" string, [], {}, -1 সব Truthy!
// ৭টি Falsy মান: console.log(Boolean(false)); // → false console.log(Boolean(0)); // → false console.log(Boolean(-0)); // → false console.log(Boolean(0n)); // → false console.log(Boolean("")); // → false console.log(Boolean(null)); // → false console.log(Boolean(undefined)); // → false console.log(Boolean(NaN)); // → false // অবাক করা Truthy মান: console.log(Boolean("0")); // → true ⚠️ "0" string! console.log(Boolean("false")); // → true ⚠️ "false" string! console.log(Boolean([])); // → true ⚠️ খালি array! console.log(Boolean({})); // → true ⚠️ খালি object! console.log(Boolean(-1)); // → true ⚠️ ঋণাত্মকও Truthy! console.log(Boolean(Infinity)); // → true // Practical ব্যবহার — কোনো মান আছে কিনা চেক: function hasValue(val) { return Boolean(val); } console.log(hasValue("")); // → false (খালি) console.log(hasValue("হ্যালো")); // → true (মান আছে) console.log(hasValue(0)); // → false ⚠️ (0 কিন্তু valid!) // তাই 0 valid হলে: val !== null && val !== undefined ব্যবহার করো।

Conversion চেইন — ধাপে ধাপে Step by Step

// String → Number → Boolean চেইন বোঝো: // ধাপ ১: "100" → Number("100") = 100 → Boolean(100) = true let strNum = "100"; console.log(Number(strNum)); // → 100 console.log(Boolean(strNum)); // → true (সরাসরি String → Boolean) // ধাপ ২: "" → Number("") = 0 → Boolean(0) = false let emptyStr = ""; console.log(Number(emptyStr)); // → 0 console.log(Boolean(emptyStr)); // → false // Object থেকে Number-এ যাওয়ার চেইন: // Object → valueOf() চেক → toString() → Number() let obj = { valueOf() { return 42; }, toString() { return "hello"; } }; console.log(Number(obj)); // → 42 (valueOf() ব্যবহার হলো) console.log(String(obj)); // → "hello" (toString() ব্যবহার হলো) console.log(obj + 0); // → 42 (valueOf() → 42+0=42)

Conversion VS Coercion — পাশাপাশি তুলনা Final Comparison

লক্ষ্য Coercion (Implicit) ⚠️ Conversion (Explicit) ✅ পার্থক্য
"42" → Number "42" - 0 = 42 Number("42") = 42 উভয়ই কাজ করে, Explicit পরিষ্কার
"42px" → Number "42px" - 0 = NaN parseInt("42px", 10) = 42 Explicit-এ সঠিক ফলাফল!
42 → String 42 + "" = "42" String(42) = "42" উভয়ই কাজ করে, Explicit স্পষ্ট
"" → Boolean if ("") = false Boolean("") = false উভয়ই সঠিক
[] → Boolean if ([]) = true (Truthy) Boolean([]) = true খালি array কিন্তু Truthy — বিভ্রান্তিকর!
তুলনা "5" == 5 = true Number("5") === 5 = true Explicit-এই নিরাপদ
সংক্ষিপ্ত সারাংশ:
Coercion = JavaScript নিজেই করে, কোড ছোট কিন্তু বিপজ্জনক।
Conversion = তুমি নিজে করো, কোড একটু বেশি কিন্তু নিরাপদ ও পরিষ্কার।
parseInt("42px", 10) কখনো "42px" - 0 দিয়ে করো না।
→ সবসময় === ব্যবহার করো — ==-এর Coercion নিয়ম মুখস্থ না করে।

🔷 Implicit Type Casting — JavaScript নিজে যা করে

Implicit Casting-এ JavaScript নিজেই ভিন্ন type-এর মান একসাথে ব্যবহার করার সময় রূপান্তর করে। এটি প্রায়ই অপ্রত্যাশিত ফলাফল দেয়।

+ অপারেটর — সবচেয়ে বিভ্রান্তিকর সাবধান!

// Number + Number = Number (যোগ): console.log(5 + 3); // → 8 ✅ // String + Number = String (জোড়া): console.log("5" + 3); // → "53" ⚠️ console.log(5 + "3"); // → "53" ⚠️ console.log("বয়স " + 22); // → "বয়স 22" (এটা ঠিক আছে) // একাধিক মান — বাম থেকে ডানে: console.log(1 + 2 + "3"); // → "33" (1+2=3, তারপর "3"+"3"="33") console.log("1" + 2 + 3); // → "123" ("1"+2="12", তারপর "12"+3="123") // Boolean + Number: console.log(true + 1); // → 2 (true → 1) console.log(false + 5); // → 5 (false → 0) console.log(true + true); // → 2 // null ও undefined: console.log(null + 1); // → 1 (null → 0) console.log(undefined + 1); // → NaN (undefined → NaN)

- * / % অপারেটর — সংখ্যায় রূপান্তর করে Numeric Context

console.log("10" - 4); // → 6 ("10" → 10) console.log("10" * "2"); // → 20 (উভয়ই Number-এ) console.log("10" / "5"); // → 2 console.log("10" % "3"); // → 1 console.log("abc" - 1); // → NaN ("abc" → NaN) console.log("10" - "abc"); // → NaN console.log(null * 5); // → 0 (null → 0) console.log(undefined * 5); // → NaN (undefined → NaN) console.log(true * 10); // → 10 (true → 1) console.log(false / 2); // → 0 (false → 0)

Comparison-এ Implicit Casting == এড়িয়ে চলো

// == (Loose) — type রূপান্তর করে: console.log("5" == 5); // → true ⚠️ console.log(0 == false); // → true ⚠️ console.log("" == false); // → true ⚠️ console.log(null == undefined);// → true ⚠️ console.log(null == 0); // → false (null শুধু undefined-এর সাথে loose equal) console.log("" == 0); // → true ⚠️ // === (Strict) — type রূপান্তর করে না: console.log("5" === 5); // → false ✅ console.log(0 === false); // → false ✅ console.log("" === false); // → false ✅

if() Context-এ Implicit Casting Boolean Context

// if()-এ যেকোনো মান → Boolean-এ রূপান্তর: if ("হ্যালো") { console.log("Truthy!"); } // → Truthy! ("হ্যালো" → true) if (42) { console.log("Truthy!"); } // → Truthy! (42 → true) if (0) { /* চলবে না */ } // (0 → false) if ("") { /* চলবে না */ } // ("" → false) if (null) { /* চলবে না */ } // (null → false) // Logical Operators-এ: console.log("হ্যালো" || "বিশ্ব"); // → "হ্যালো" (প্রথমটা truthy) console.log("" || "বিশ্ব"); // → "বিশ্ব" (প্রথমটা falsy) console.log("হ্যালো" && "বিশ্ব"); // → "বিশ্ব" (দ্বিতীয়টা ফেরত) console.log("" && "বিশ্ব"); // → "" (প্রথমটা falsy, সেটাই ফেরত)
⚠️ Implicit Casting এড়ানোর সেরা উপায়:
→ সবসময় === ব্যবহার করো, == নয়।
→ মান রূপান্তর করতে হলে সবসময় Explicit Casting ব্যবহার করো।
→ কখনো + দিয়ে Number-এ রূপান্তর করো না (+"5"), বরং Number("5") ব্যবহার করো।

🔷 Explicit Casting ১ — String-এ রূপান্তর

যেকোনো মানকে String-এ রূপান্তর করার তিনটি প্রধান উপায় আছে।

পদ্ধতি ১ — String(value) সবচেয়ে নিরাপদ

console.log(String(42)); // → "42" console.log(String(3.14)); // → "3.14" console.log(String(-7)); // → "-7" console.log(String(true)); // → "true" console.log(String(false)); // → "false" console.log(String(null)); // → "null" ✅ (null-ও handle করে) console.log(String(undefined)); // → "undefined" ✅ console.log(String(NaN)); // → "NaN" console.log(String(Infinity)); // → "Infinity" console.log(String([1, 2, 3])); // → "1,2,3" console.log(String({a: 1})); // → "[object Object]"

পদ্ধতি ২ — .toString() Radix সহ

console.log((42).toString()); // → "42" console.log((3.14).toString()); // → "3.14" console.log(true.toString()); // → "true" // Radix (ভিত্তি) দিয়ে সংখ্যার ভিন্ন রূপ: console.log((255).toString(2)); // → "11111111" (Binary) console.log((255).toString(8)); // → "377" (Octal) console.log((255).toString(16)); // → "ff" (Hexadecimal) // ⚠️ null ও undefined-এ কাজ করে না: // null.toString() → TypeError! // undefined.toString() → TypeError!

পদ্ধতি ৩ — Template Literal সহজ পদ্ধতি

let num = 100; let bool = true; let str1 = `${num}`; // → "100" let str2 = `${bool}`; // → "true" let str3 = `মান: ${num}`; // → "মান: 100" console.log(typeof str1); // → "string" ✅

String রূপান্তর — সম্পূর্ণ টেবিল Reference

মূল মান মূল Type String ফলাফল
42 Number "42"
3.14 Number "3.14"
0 Number "0"
NaN Number "NaN"
Infinity Number "Infinity"
true Boolean "true"
false Boolean "false"
null null "null"
undefined undefined "undefined"
[1, 2, 3] Array "1,2,3"
{a: 1} Object "[object Object]"
কোন পদ্ধতি ব্যবহার করবে?
→ সাধারণভাবে: String(value) — সবকিছু handle করে, নিরাপদ।
→ সংখ্যার ভিত্তি বদলাতে: (num).toString(16) ← hex ইত্যাদি।
→ পেজে দেখাতে: Template Literal `${value}`

🔷 Explicit Casting ২ — Number-এ রূপান্তর

যেকোনো মানকে Number-এ রূপান্তর করার বেশ কয়েকটি পদ্ধতি আছে। প্রতিটির আলাদা আচরণ জানা দরকার।

পদ্ধতি ১ — Number(value) কঠোর রূপান্তর

// String → Number: console.log(Number("42")); // → 42 console.log(Number("3.14")); // → 3.14 console.log(Number("-10")); // → -10 console.log(Number(" 42 ")); // → 42 (whitespace ছাঁটে) console.log(Number("")); // → 0 (খালি string = 0) console.log(Number("42abc")); // → NaN ⚠️ (শেষে অক্ষর থাকায়) console.log(Number("abc")); // → NaN // Boolean → Number: console.log(Number(true)); // → 1 console.log(Number(false)); // → 0 // বিশেষ মান: console.log(Number(null)); // → 0 console.log(Number(undefined)); // → NaN ⚠️ console.log(Number([])); // → 0 (খালি array = 0) console.log(Number([5])); // → 5 (একটি মানের array) console.log(Number([1, 2])); // → NaN (একাধিক মানের array) console.log(Number({})); // → NaN

পদ্ধতি ২ — parseInt(string, radix) পূর্ণ সংখ্যা

console.log(parseInt("42")); // → 42 console.log(parseInt("42.9")); // → 42 (দশমিক কাটা) console.log(parseInt("42abc")); // → 42 ✅ (শেষের abc উপেক্ষা) console.log(parseInt("abc42")); // → NaN (শুরুতেই অক্ষর) console.log(parseInt(" 100 ")); // → 100 (whitespace ছাঁটে) console.log(parseInt("")); // → NaN (Number("") ≠ parseInt("")) // Radix দিয়ে বিভিন্ন ভিত্তিতে পড়া: console.log(parseInt("ff", 16)); // → 255 (hex → decimal) console.log(parseInt("11111111", 2)); // → 255 (binary → decimal) console.log(parseInt("0xFF", 16)); // → 255

পদ্ধতি ৩ — parseFloat(string) দশমিক সংখ্যা

console.log(parseFloat("3.14")); // → 3.14 console.log(parseFloat("3.14abc")); // → 3.14 ✅ console.log(parseFloat("3.14.99")); // → 3.14 (দ্বিতীয় . উপেক্ষা) console.log(parseFloat("abc3.14")); // → NaN console.log(parseFloat(" 2.5 ")); // → 2.5 // parseInt vs parseFloat পার্থক্য: console.log(parseInt("3.9")); // → 3 (দশমিক কাটে) console.log(parseFloat("3.9")); // → 3.9 (দশমিক রাখে)

Number রূপান্তর — সম্পূর্ণ তুলনা টেবিল Reference

মূল মান Number() parseInt() parseFloat()
"42" 42 42 42
"3.14" 3.14 3 ✂️ 3.14
"42abc" NaN ⚠️ 42 42
"abc" NaN NaN NaN
"" (খালি) 0 NaN ⚠️ NaN ⚠️
true 1 NaN NaN
false 0 NaN NaN
null 0 NaN NaN
undefined NaN NaN NaN
কোন পদ্ধতি কখন?
→ পুরো String সংখ্যা হলে: Number("42")
→ String-এর শুরুতে সংখ্যা, পেছনে text থাকলে: parseInt("42px")
→ দশমিক দরকার হলে: parseFloat("3.14rem")
→ ফর্ম ইনপুটে সবসময়: Number(input) বা parseInt(input, 10)

🔷 Explicit Casting ৩ — Boolean-এ রূপান্তর

যেকোনো মানকে Boolean-এ রূপান্তর করার দুটি পদ্ধতি আছে। এটি Falsy ও Truthy মান বোঝার সাথে সরাসরি সংযুক্ত।

পদ্ধতি ১ — Boolean(value) স্পষ্ট পদ্ধতি

// Falsy মান → false: console.log(Boolean(false)); // → false console.log(Boolean(0)); // → false console.log(Boolean(-0)); // → false console.log(Boolean(0n)); // → false (BigInt শূন্য) console.log(Boolean("")); // → false (খালি string) console.log(Boolean(null)); // → false console.log(Boolean(undefined)); // → false console.log(Boolean(NaN)); // → false // Truthy মান → true: console.log(Boolean(1)); // → true console.log(Boolean(-1)); // → true (ঋণাত্মকও Truthy) console.log(Boolean("0")); // → true ⚠️ ("0" string!) console.log(Boolean("false")); // → true ⚠️ ("false" string!) console.log(Boolean([])); // → true ⚠️ (খালি array!) console.log(Boolean({})); // → true ⚠️ (খালি object!) console.log(Boolean(" ")); // → true (space-ও Truthy)

পদ্ধতি ২ — !! (Double Negation) সংক্ষিপ্ত

console.log(!!"হ্যালো"); // → true ("হ্যালো" truthy, ! → false, ! → true) console.log(!!""); // → false ("" falsy, ! → true, ! → false) console.log(!!0); // → false console.log(!!42); // → true console.log(!!null); // → false console.log(!!undefined); // → false // Boolean() ও !! একই ফলাফল দেয়: console.log(Boolean("test") === !!"test"); // → true

Boolean রূপান্তর — সম্পূর্ণ Truthy/Falsy টেবিল ⭐ মুখস্থ করো

মান Boolean ফলাফল ধরন নোট
false false Boolean
0, -0 false Number
0n false BigInt BigInt শূন্য
"", '', `` false String খালি string
null false null
undefined false undefined
NaN false Number
"0" true String ⚠️ "0" String, শূন্য নয়!
"false" true String ⚠️ "false" String!
[] true Array ⚠️ খালি array-ও Truthy!
{} true Object ⚠️ খালি object-ও Truthy!
যেকোনো সংখ্যা ≠ 0 true Number ঋণাত্মকও Truthy
যেকোনো non-empty String true String Space-ও Truthy
⚠️ সাধারণ ভুল:
Boolean("false")true — কারণ এটি একটি non-empty String!
Boolean("0")true — কারণ এটি String, Number 0 নয়!
Boolean([])true — খালি Array-ও Truthy!

🔷 Object থেকে Primitive রূপান্তর

JavaScript কোনো Object-কে Primitive-এ রূপান্তর করার দরকার হলে সেই Object-এর valueOf()toString() method ব্যবহার করে।

valueOf()toString() Default আচরণ

const obj = { name: "করিম", score: 95 }; // সাধারণ Object: console.log(String(obj)); // → "[object Object]" (toString() ডাকে) console.log(Number(obj)); // → NaN (valueOf() → toString() → NaN) // Array: const arr = [1, 2, 3]; console.log(String(arr)); // → "1,2,3" console.log(Number(arr)); // → NaN (একাধিক মান) console.log(Number([5])); // → 5 (একটি মান) // Date: const date = new Date(2025, 0, 1); console.log(String(date)); // → "Wed Jan 01 2025 ..." console.log(Number(date)); // → 1735689600000 (milliseconds)

Custom Object-এ রূপান্তর নিয়ন্ত্রণ Override

const product = { name: "চাল", price: 65, // Number context-এ এই method ডাকা হবে: valueOf() { return this.price; }, // String context-এ এই method ডাকা হবে: toString() { return `${this.name} (৳${this.price})`; } }; console.log(Number(product)); // → 65 (valueOf() ডেকেছে) console.log(String(product)); // → "চাল (৳65)" (toString() ডেকেছে) console.log(product + 10); // → 75 (valueOf() → 65 + 10) console.log(`পণ্য: ${product}`); // → "পণ্য: চাল (৳65)" (toString())

🔷 সাধারণ Type Casting ভুল ও সমাধান

JavaScript-এ Type Casting নিয়ে অনেক সাধারণ ভুল হয়। উদাহরণসহ দেখো কোথায় সমস্যা এবং কীভাবে ঠিক করতে হয়:

ভুল ১ — ফর্ম ইনপুটে গণনা সাধারণ ভুল

// ❌ ভুল — ইনপুট সবসময় String: let a = "10"; // ইনপুট থেকে আসা let b = "20"; console.log(a + b); // → "1020" ⚠️ (গণনা নয়!) // ✅ সমাধান — আগে Number-এ রূপান্তর করো: let numA = Number(a); let numB = Number(b); console.log(numA + numB); // → 30 ✅

ভুল ২ — NaN চেক সাধারণ ভুল

// ❌ ভুল — NaN নিজের সমান নয়: let result = Number("abc"); if (result === NaN) { console.log("NaN পেয়েছি"); // কখনো চলবে না! } // ✅ সমাধান: if (Number.isNaN(result)) { console.log("NaN পেয়েছি"); // → NaN পেয়েছি ✅ } // অথবা: if (isNaN(result)) { console.log("NaN পেয়েছি"); // → NaN পেয়েছি ✅ }

ভুল ৩ — == দিয়ে তুলনা সাধারণ ভুল

// ❌ ভুল — == Implicit Casting করে: console.log(0 == ""); // → true ⚠️ console.log(0 == false); // → true ⚠️ console.log("" == false); // → true ⚠️ console.log(null == 0); // → false (এখানে null আলাদা আচরণ করে) console.log(null == undefined); // → true ⚠️ // ✅ সমাধান — সবসময় === ব্যবহার করো: console.log(0 === ""); // → false ✅ console.log(0 === false); // → false ✅ console.log(null === undefined);// → false ✅

ভুল ৪ — parseInt ছাড়া radix ভালো অভ্যাস

// ⚠️ radix না দিলে পুরনো ব্রাউজারে সমস্যা হতে পারে: console.log(parseInt("08")); // কিছু পুরনো জায়গায় সমস্যা // ✅ সবসময় radix দাও: console.log(parseInt("08", 10)); // → 8 ✅ (decimal) console.log(parseInt("ff", 16)); // → 255 ✅ (hexadecimal)

ভুল ৫ — খালি Array ও Object-এর Boolean অবাক করা আচরণ

// ⚠️ খালি Array ও Object Truthy: if ([]) { console.log("[] Truthy"); } // → [] Truthy ⚠️ if ({}) { console.log("{} Truthy"); } // → {} Truthy ⚠️ // ✅ Array খালি কিনা চেক করার সঠিক উপায়: let arr = []; if (arr.length === 0) { console.log("Array খালি"); // → Array খালি ✅ } // ✅ Object খালি কিনা চেক: let obj = {}; if (Object.keys(obj).length === 0) { console.log("Object খালি"); // → Object খালি ✅ }

🔷 দ্রুত রেফারেন্স — JavaScript Type Casting

Explicit Casting পদ্ধতিসমূহ Methods

লক্ষ্য Type সেরা পদ্ধতি বিকল্প এড়িয়ে চলো
→ String String(val) `${val}` val + ""
→ Number (পূর্ণ) Number(val) parseInt(val, 10) +val, val * 1
→ Number (দশমিক) parseFloat(val) Number(val) +val
→ Boolean Boolean(val) !!val Implicit (if ছাড়া)

Implicit Casting — বিপজ্জনক উদাহরণ এক নজরে মনে রাখো

Expression ফলাফল কেন?
"5" + 3 "53" ⚠️ String + Number = Concatenation
"5" - 3 2 - শুধু Number-এ কাজ করে, "5" → 5
true + 1 2 true → 1
null + 1 1 null → 0
undefined + 1 NaN undefined → NaN
"5" == 5 true ⚠️ == type ignore করে
"5" === 5 false === type সহ তুলনা
Boolean("0") true ⚠️ "0" String, শূন্য নয়
Boolean([]) true ⚠️ Object সবসময় Truthy
Number("") 0 ⚠️ খালি String = 0
parseInt("", 10) NaN parseInt খালি String = NaN

Type Casting-এর মূল নিয়ম Golden Rules

# নিয়ম
সবসময় === ব্যবহার করো, == এড়িয়ে চলো।
রূপান্তর করতে Explicit পদ্ধতি (Number(), String()) ব্যবহার করো।
NaN চেক করতে Number.isNaN() ব্যবহার করো।
ফর্ম ইনপুট গণনায় ব্যবহারের আগে Number() দিয়ে রূপান্তর করো।
parseInt()-এ সবসময় radix (10) দাও।
Array খালি কিনা arr.length === 0 দিয়ে চেক করো, !arr নয়।
+value বা value * 1 দিয়ে Implicit Casting করো না।

🧠 নিজেকে যাচাই করো

1. Number('123') কী return করে?

2. NaN মানে কী?

3. Boolean('') কী return করে?

✏️ Task — এখন তুমি করো

'123', true, null, [] — এগুলো Number() ও Boolean()-এ convert করে দেখো।

ধাপ 4🏗️ Real Project — Interactive Portfolio

Portfolio-এ age calculator বানাও — type casting ব্যবহার করো।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio form-এর input value number-এ convert করো।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

🏗️ JavaScript Data Structures — সম্পূর্ণ নোট

এই সেকশনে JavaScript-এর Array, Object, Map, Set, WeakMap, WeakSet, Stack ও Queue — সব Data Structure বাংলায় উদাহরণসহ আলোচনা করা হয়েছে।


🔷 Data Structures কী ও কেন প্রয়োজন?

Data Structure হলো তথ্য সংগঠিতভাবে সংরক্ষণ ও পরিচালনা করার পদ্ধতি। সঠিক Data Structure বেছে নিলে প্রোগ্রাম দ্রুত ও কার্যকরভাবে কাজ করে।

সহজ উদাহরণ — একটি শ্রেণির ছাত্রছাত্রীর নামের তালিকা রাখতে Array, প্রতিটি ছাত্রের তথ্য (নাম, বয়স, ঠিকানা) রাখতে Object সবচেয়ে উপযুক্ত।

Data Structure কী রাখে? কখন ব্যবহার করবে? ES Version
Array তালিকা আকারে একাধিক মান ক্রম গুরুত্বপূর্ণ হলে, index দিয়ে access ES1
Object Key-Value জোড়া নামযুক্ত তথ্য রাখতে ES1
Map Key-Value জোড়া (যেকোনো Key) Key যেকোনো type হলে, iteration দরকার হলে ES6
Set অনন্য (unique) মানের সংগ্রহ duplicate বাদ দিতে, membership চেক ES6
WeakMap Object Key সহ Key-Value Private data, memory leak এড়াতে ES6
WeakSet Object-এর unique সংগ্রহ Object tracking, memory safe ES6
Stack LIFO — শেষে রাখা, আগে বের হয় Undo/Redo, Function call stack Array দিয়ে তৈরি
Queue FIFO — আগে রাখা, আগে বের হয় Task queue, Print queue Array দিয়ে তৈরি

🔷 Indexed Collections — সংখ্যাভিত্তিক সংগ্রহ

Indexed Collections হলো সেই Data Structure যেখানে প্রতিটি মান একটি numeric index দিয়ে access করা যায়। JavaScript-এ দুই ধরনের Indexed Collection আছে।

ধরন কী রাখে? Index ব্যবহার
Array যেকোনো type মিশিয়ে 0, 1, 2 ... সাধারণ তালিকা, সব ধরনের কাজ
Typed Array শুধু নির্দিষ্ট numeric type 0, 1, 2 ... Binary data, WebGL, Audio/Video, Network
মনে রাখো: সাধারণ কাজে সবসময় Array ব্যবহার করো। Typed Array শুধু তখন দরকার যখন নির্দিষ্ট ধরনের binary data নিয়ে কাজ করতে হয় — যেমন ছবি প্রক্রিয়াকরণ, WebGL, বা নেটওয়ার্ক প্রোটোকল।

🔷 Array — তালিকা

Array হলো index-ভিত্তিক তালিকা যেখানে ক্রমানুসারে একাধিক মান রাখা যায়। Index সবসময় 0 থেকে শুরু।

Array তৈরি ও Access Creation

// Array তৈরির উপায়: const fruits = ["আম", "কলা", "লিচু"]; // Array Literal — সবচেয়ে ভালো const numbers = new Array(1, 2, 3); // new Array() — এড়িয়ে চলো const mixed = [1, "হ্যালো", true, null]; // মিশ্র type const matrix = [[1,2], [3,4], [5,6]]; // 2D Array // Access — index দিয়ে: console.log(fruits[0]); // → আম (প্রথম) console.log(fruits[2]); // → লিচু (তৃতীয়) console.log(fruits[fruits.length - 1]); // → লিচু (শেষ) console.log(fruits.at(-1)); // → লিচু (ES2022 — শেষ element) console.log(fruits.at(-2)); // → কলা (শেষ থেকে দ্বিতীয়) // নেই এমন index: console.log(fruits[10]); // → undefined // length: console.log(fruits.length); // → 3

Array Destructuring ES6

const colors = ["লাল", "সবুজ", "নীল", "হলুদ"]; // সাধারণ destructuring: const [first, second, third] = colors; console.log(first); // → লাল console.log(second); // → সবুজ // কিছু skip করা: const [, , blue] = colors; console.log(blue); // → নীল // Rest — বাকি সব: const [primary, ...rest] = colors; console.log(primary); // → লাল console.log(rest); // → ["সবুজ", "নীল", "হলুদ"] // Default মান: const [a, b, c, d, e = "কমলা"] = colors; console.log(e); // → হলুদ (colors[4] নেই, তাই default নয়, আছে হলুদ) // দুটো Variable swap: let x = 1, y = 2; [x, y] = [y, x]; console.log(x, y); // → 2 1

Spread Operator (...) ES6

const arr1 = [1, 2, 3]; const arr2 = [4, 5, 6]; // Array copy: const copy = [...arr1]; // → [1, 2, 3] (নতুন array) // Array merge: const merged = [...arr1, ...arr2]; // → [1, 2, 3, 4, 5, 6] const withExtra = [...arr1, 10, ...arr2]; // → [1, 2, 3, 10, 4, 5, 6] // Function-এ spread: const nums = [3, 1, 4, 1, 5, 9]; console.log(Math.max(...nums)); // → 9 (array-কে আলাদা argument করে) // String → Array: const chars = [..."হ্যালো"]; console.log(chars); // → ["হ", "্", "য", "া", "ল", "ো"]

Mutating Methods — মূল Array পরিবর্তন করে মূল পরিবর্তন হয়

Method কাজ উদাহরণ Return
.push(item) শেষে যোগ arr.push(4) নতুন length
.pop() শেষেরটা সরায় arr.pop() সরানো element
.unshift(item) শুরুতে যোগ arr.unshift(0) নতুন length
.shift() শুরুরটা সরায় arr.shift() সরানো element
.splice(i, n, ...items) নির্দিষ্ট জায়গায় যোগ/বাদ arr.splice(1, 2) সরানো elements
.sort(fn) সাজানো arr.sort() সাজানো Array
.reverse() উল্টানো arr.reverse() উল্টানো Array
.fill(val, s, e) মান দিয়ে পূরণ arr.fill(0) পরিবর্তিত Array
let fruits = ["আম", "কলা", "লিচু"]; // push / pop: fruits.push("পেয়ারা"); // শেষে যোগ console.log(fruits); // → ["আম", "কলা", "লিচু", "পেয়ারা"] fruits.pop(); // শেষেরটা বাদ console.log(fruits); // → ["আম", "কলা", "লিচু"] // unshift / shift: fruits.unshift("আনারস"); // শুরুতে যোগ console.log(fruits); // → ["আনারস", "আম", "কলা", "লিচু"] fruits.shift(); // শুরুরটা বাদ console.log(fruits); // → ["আম", "কলা", "লিচু"] // splice(শুরু, কতটা বাদ, ...নতুন): fruits.splice(1, 1, "আপেল", "নাশপাতি"); console.log(fruits); // → ["আম", "আপেল", "নাশপাতি", "লিচু"] // sort — সংখ্যার সঠিক sort: const nums = [10, 1, 21, 2]; nums.sort(); // ⚠️ → [1, 10, 2, 21] (String sort!) nums.sort((a, b) => a - b); // ✅ → [1, 2, 10, 21] (Number sort) nums.sort((a, b) => b - a); // ✅ → [21, 10, 2, 1] (Descending)

Non-Mutating Methods — নতুন Array ফেরত দেয় মূল অপরিবর্তিত

Method কাজ উদাহরণ
.slice(s, e) অংশ বের করে নতুন Array [1,2,3,4].slice(1,3) → [2,3]
.concat(...arr) জোড়া লাগিয়ে নতুন Array [1,2].concat([3,4]) → [1,2,3,4]
.join(sep) String-এ পরিণত ["ক","খ"].join("-") → "ক-খ"
.indexOf(val) প্রথম index খোঁজে [1,2,3].indexOf(2) → 1
.lastIndexOf(val) শেষ index খোঁজে [1,2,1].lastIndexOf(1) → 2
.includes(val) আছে কিনা [1,2,3].includes(2) → true
.flat(depth) Nested array সমতল করে [1,[2,[3]]].flat(2) → [1,2,3]
.toReversed() উল্টো নতুন Array (ES2023) মূল অপরিবর্তিত
.toSorted(fn) সাজানো নতুন Array (ES2023) মূল অপরিবর্তিত

Iterative Methods — প্রতিটি element-এ কাজ করে Iteration

const students = [ { name: "করিম", score: 85 }, { name: "রাহেলা", score: 92 }, { name: "সজল", score: 55 }, { name: "নিলুফার",score: 78 }, ]; // forEach — প্রতিটিতে কাজ করে, কিছু ফেরত দেয় না: students.forEach(s => console.log(`${s.name}: ${s.score}`)); // map — প্রতিটি রূপান্তর করে নতুন Array: const names = students.map(s => s.name); console.log(names); // → ["করিম", "রাহেলা", "সজল", "নিলুফার"] const grades = students.map(s => s.score >= 60 ? "পাস" : "ফেল"); console.log(grades); // → ["পাস", "পাস", "ফেল", "পাস"] // filter — শর্তপূরণকারীদের নতুন Array: const passed = students.filter(s => s.score >= 60); console.log(passed.length); // → 3 // find — প্রথম মিলটা ফেরত: const topStudent = students.find(s => s.score > 90); console.log(topStudent.name); // → রাহেলা // findIndex — প্রথম মিলের index: const idx = students.findIndex(s => s.score < 60); console.log(idx); // → 2 // some — অন্তত একটি শর্ত পূরণ? console.log(students.some(s=> s.score > 90)); // → true // every — সবাই শর্ত পূরণ? console.log(students.every(s => s.score > 50)); // → true // reduce — একটি মানে সংকুচিত: const total = students.reduce((sum, s) => sum + s.score, 0); console.log(total); // → 310 const avg = total / students.length; console.log(avg.toFixed(1)); // → 77.5 // flat ও flatMap: const nested = [[1, 2], [3, 4], [5]]; console.log(nested.flat()); // → [1, 2, 3, 4, 5] const doubled = nested.flatMap(arr => arr.map(x => x * 2)); console.log(doubled); // → [2, 4, 6, 8, 10]

Static Array Methods Static

// Array.isArray() — Array কিনা চেক: console.log(Array.isArray([1,2,3])); // → true console.log(Array.isArray("hello")); // → false // Array.from() — Array-like → Array: console.log(Array.from("hello")); // → ["h","e","l","l","o"] console.log(Array.from({length:5}, (_, i) => i + 1)); // → [1,2,3,4,5] // Array.of() — arguments → Array: console.log(Array.of(1, 2, 3)); // → [1, 2, 3] console.log(Array.of(7)); // → [7] (new Array(7) ≠ Array.of(7)!)
⚠️ sort() সাবধান: কোনো function না দিলে সব মান String-এ convert করে sort করে। তাই [10, 2, 1].sort()[1, 10, 2] (ভুল!)। সংখ্যার জন্য সবসময় .sort((a, b) => a - b) দাও।

🔷 Typed Arrays — নির্দিষ্ট ধরনের সংখ্যার Array

Typed Array হলো নির্দিষ্ট numeric type-এর binary data রাখার বিশেষ Array। সাধারণ Array-এর মতো দেখতে হলেও এটি শুধু নির্দিষ্ট ধরনের সংখ্যা রাখে এবং মেমোরি অনেক কার্যকরভাবে ব্যবহার করে।

ArrayBuffer — Binary Data-র ভিত্তি Buffer

// ArrayBuffer — 16 byte-এর একটি raw memory block: const buffer = new ArrayBuffer(16); console.log(buffer.byteLength); // → 16 // সরাসরি পড়া যায় না — View দরকার: const int32View = new Int32Array(buffer); int32View[0] = 42; int32View[1] = 100; console.log(int32View[0]); // → 42 console.log(int32View.length); // → 4 (16 bytes / 4 bytes প্রতি int32)

Typed Array-এর প্রকারসমূহ Types

Type প্রতি element মানের পরিসর ব্যবহার
Int8Array 1 byte -128 থেকে 127 ছোট পূর্ণ সংখ্যা
Uint8Array 1 byte 0 থেকে 255 ছবির pixel, binary data
Uint8ClampedArray 1 byte 0 থেকে 255 (clamped) Canvas pixel data
Int16Array 2 bytes -32768 থেকে 32767 Audio data
Uint16Array 2 bytes 0 থেকে 65535
Int32Array 4 bytes -2³¹ থেকে 2³¹-1 সাধারণ integer
Uint32Array 4 bytes 0 থেকে 2³²-1
Float32Array 4 bytes 32-bit float WebGL, 3D graphics
Float64Array 8 bytes 64-bit float সাধারণ Number-এর মতো
BigInt64Array 8 bytes BigInt পূর্ণ সংখ্যা বড় সংখ্যা

Typed Array ব্যবহার Usage

// Int32Array তৈরি: const int32 = new Int32Array(4); // 4টি Int32 মান int32[0] = 10; int32[1] = 20; int32[2] = 30; int32[3] = 40; console.log(int32); // → Int32Array [10, 20, 30, 40] // initial data সহ: const floats = new Float32Array([1.1, 2.2, 3.3]); console.log(floats[0]); // → 1.100000023841858 (float precision) // Uint8Array — binary/pixel data: const pixels = new Uint8Array([255, 128, 0, 255]); // R, G, B, A console.log(pixels[0]); // → 255 (লাল) // সাধারণ Array-এর মতো method আছে: const nums = new Int16Array([5, 3, 8, 1, 9]); console.log(nums.length); // → 5 console.log(nums.indexOf(8)); // → 2 // Typed Array → সাধারণ Array: const regular = Array.from(nums); const regular2 = [...nums];

DataView — Mixed Type Buffer Reading DataView

const buffer = new ArrayBuffer(8); const view = new DataView(buffer); // বিভিন্ন type-এ write: view.setInt8(0, 127); // byte 0-এ Int8 view.setInt16(1, 1000); // byte 1-2-এ Int16 view.setFloat32(3, 3.14); // byte 3-6-এ Float32 // পড়া: console.log(view.getInt8(0)); // → 127 console.log(view.getInt16(1)); // → 1000 console.log(view.getFloat32(3)); // → 3.140000104904175
কখন Typed Array ব্যবহার করবে?
→ Canvas API-তে pixel manipulation (Uint8ClampedArray)।
→ WebGL-এ 3D vertex data (Float32Array)।
→ Web Audio API-তে sound data (Float32Array)।
→ Fetch API বা WebSocket-এ binary data পড়তে।
→ সাধারণ কাজে ব্যবহার করো না — normal Array-ই যথেষ্ট।

🔷 Object — Key-Value Store

Object হলো Key-Value জোড়ায় তথ্য সংরক্ষণের পাত্র। Key সবসময় String বা Symbol — এটিই Array-এর সাথে মূল পার্থক্য।

Object তৈরি, Access ও পরিবর্তন Basics

// Object Literal: const student = { name: "রাহেলা", age: 20, score: 92, address: { city: "ঢাকা", area: "মিরপুর" }, hobbies: ["পড়া", "ছবি আঁকা"] }; // Access: console.log(student.name); // → রাহেলা (Dot) console.log(student["score"]); // → 92 (Bracket) console.log(student.address.city); // → ঢাকা (Nested) console.log(student.hobbies[0]); // → পড়া // Dynamic key: const key = "name"; console.log(student[key]); // → রাহেলা // Optional Chaining — নেই হলে Error নয়, undefined: console.log(student.grade?.letter); // → undefined (grade নেই, Error নেই) console.log(student.address?.city); // → ঢাকা // যোগ, পরিবর্তন, মুছে ফেলা: student.email = "rahela@example.com"; // নতুন যোগ student.age = 21; // পরিবর্তন delete student.score; // মুছে ফেলা

Object Destructuring ও Spread ES6

const product = { name: "চাল", price: 65, qty: 100, unit: "কেজি" }; // Destructuring: const { name, price } = product; console.log(name, price); // → চাল 65 // নতুন নামে: const { name: productName, price: taka } = product; console.log(productName, taka); // → চাল 65 // Default মান: const { discount = 0 } = product; console.log(discount); // → 0 (product-এ নেই) // Rest: const { name: n, ...rest } = product; console.log(n); // → চাল console.log(rest); // → { price: 65, qty: 100, unit: "কেজি" } // Spread — Object copy ও merge: const copy = { ...product }; // shallow copy const updated = { ...product, price: 70 }; // পরিবর্তিত copy const merged = { ...product, brand: "প্রাণ" }; // নতুন key যোগ console.log(updated.price); // → 70 console.log(product.price); // → 65 (মূল অপরিবর্তিত)

গুরুত্বপূর্ণ Object Static Methods Methods

const user = { name: "করিম", age: 25, city: "ঢাকা" }; // keys / values / entries: console.log(Object.keys(user)); // → ["name", "age", "city"] console.log(Object.values(user)); // → ["করিম", 25, "ঢাকা"] console.log(Object.entries(user)); // → [["name","করিম"],["age",25],["city","ঢাকা"]] // entries → Object: const entries = [["a", 1], ["b", 2]]; const obj = Object.fromEntries(entries); console.log(obj); // → { a: 1, b: 2 } // assign — merge: const defaults = { theme: "light", lang: "bn" }; const userPrefs = { lang: "en" }; const settings = Object.assign({}, defaults, userPrefs); console.log(settings); // → { theme: "light", lang: "en" } // freeze — পরিবর্তন বন্ধ: const config = Object.freeze({ version: "1.0" }); config.version = "2.0"; // চুপচাপ ব্যর্থ console.log(config.version); // → "1.0" // hasOwn (ES2022) / hasOwnProperty: console.log(Object.hasOwn(user, "name")); // → true console.log(Object.hasOwn(user, "email")); // → false // for...in — সব enumerable key-এ loop: for (const key in user) { console.log(`${key}: ${user[key]}`); }

🔷 Keyed Collections — Key-ভিত্তিক সংগ্রহ

Keyed Collections হলো সেই Data Structure যেখানে প্রতিটি মান একটি Key দিয়ে চেনা যায়। Indexed Collection (Array)-এর মতো সংখ্যাভিত্তিক নয় — এখানে Key যেকোনো কিছু হতে পারে।

Collection Key-এর type Value Garbage Collection Iterable
Map যেকোনো type যেকোনো type ❌ না ✅ হ্যাঁ
WeakMap শুধু Object যেকোনো type ✅ হ্যাঁ ❌ না
Set মানটিই Key Unique মান ❌ না ✅ হ্যাঁ
WeakSet শুধু Object Object-ই মান ✅ হ্যাঁ ❌ না
Object vs Keyed Collections:
Object → সাধারণ structured data, JSON-friendly।
Map → যখন Key যেকোনো type হবে বা ঘন ঘন add/delete হবে।
Set → যখন শুধু unique মান রাখতে হবে।
WeakMap/WeakSet → memory-sensitive private data।

🔷 Map — উন্নত Key-Value Store

Map হলো ES6-এর Key-Value structure। Object-এর মতো হলেও Map-এ Key যেকোনো type-এর হতে পারে — Object, Array, Function, Number সবকিছু।

Map vs Object — পার্থক্য Comparison

বিষয় Object Map
Key-এর type শুধু String বা Symbol যেকোনো type
Insertion Order সাধারণত বজায় থাকে (integer key ছাড়া) সর্বদা বজায় থাকে
Size জানা Object.keys(obj).length map.size
Iteration for...in, Object.entries() সরাসরি iterable
Default Key Prototype-এর key থাকে শুধু নিজের key
Performance সাধারণ data-এ ভালো ঘন ঘন add/delete-এ ভালো

Map তৈরি ও Methods Usage

// Map তৈরি: const map = new Map(); // set() — Key-Value যোগ: map.set("name", "করিম"); map.set("age", 25); map.set(true, "boolean key"); // Boolean key map.set(42, "number key"); // Number key // Object-কে key হিসেবে! const objKey = { id: 1 }; map.set(objKey, "object key ব্যবহার"); // get() — মান পড়া: console.log(map.get("name")); // → করিম console.log(map.get(true)); // → boolean key console.log(map.get(objKey)); // → object key ব্যবহার // has() — আছে কিনা: console.log(map.has("name")); // → true console.log(map.has("email")); // → false // size: console.log(map.size); // → 5 // delete(): map.delete("age"); console.log(map.size); // → 4 // Map তৈরিতে initial data: const scores = new Map([ ["করিম", 85], ["রাহেলা", 92], ["সজল", 78], ]); // Iteration: for (const [name, score] of scores) { console.log(`${name}: ${score}`); } // → করিম: 85 // → রাহেলা: 92 // → সজল: 78 scores.forEach((score, name) => { console.log(`${name} পেয়েছে ${score}`); }); // Keys, Values, Entries: console.log([...scores.keys()]); // → ["করিম", "রাহেলা", "সজল"] console.log([...scores.values()]); // → [85, 92, 78] // Map → Object: const obj = Object.fromEntries(scores); // Object → Map: const map2 = new Map(Object.entries(obj));

Map পরিষ্কার ও কখন ব্যবহার করবে? Use Cases

const cache = new Map(); // cache হিসেবে Map ব্যবহার: function getUser(id) { if (cache.has(id)) { console.log("Cache থেকে পাওয়া!"); return cache.get(id); } const user = { id, name: `User ${id}` }; // Database থেকে আনার মতো cache.set(id, user); return user; } getUser(1); // নতুন getUser(1); // Cache থেকে // clear() — সব মুছে ফেলা: cache.clear(); console.log(cache.size); // → 0

🔷 Set — অনন্য মানের সংগ্রহ

Set-এ প্রতিটি মান সর্বদা অনন্য — একই মান দুবার রাখা যায় না। Duplicate মান যোগ করলে চুপচাপ উপেক্ষিত হয়।

Set তৈরি ও Methods Usage

// Set তৈরি: const set = new Set(); // add() — মান যোগ: set.add(1); set.add(2); set.add(3); set.add(2); // Duplicate — উপেক্ষিত set.add(1); // Duplicate — উপেক্ষিত console.log(set); // → Set(3) { 1, 2, 3 } console.log(set.size); // → 3 (duplicate গোনা হয়নি) // has() — আছে কিনা: console.log(set.has(2)); // → true console.log(set.has(5)); // → false // delete(): set.delete(2); console.log(set); // → Set(2) { 1, 3 } // initial data সহ: const cities = new Set(["ঢাকা", "চট্টগ্রাম", "সিলেট", "ঢাকা"]); console.log(cities); // → Set(3) {"ঢাকা", "চট্টগ্রাম", "সিলেট"} // Iteration: for (const city of cities) { console.log(city); } cities.forEach(city => console.log(city)); // Set → Array: const arr = [...cities]; const arr2 = Array.from(cities);

Array থেকে Duplicate সরানো সেরা ব্যবহার

// Array-এ duplicate আছে: const tags = ["js", "css", "js", "html", "css", "js"]; // Set দিয়ে duplicate সরানো — ১ লাইনে: const uniqueTags = [...new Set(tags)]; console.log(uniqueTags); // → ["js", "css", "html"] // সংখ্যায়: const nums = [1, 2, 3, 2, 1, 4, 3, 5]; const unique = [...new Set(nums)]; console.log(unique); // → [1, 2, 3, 4, 5]

Set দিয়ে গণিতের Set অপারেশন Set Operations

const setA = new Set([1, 2, 3, 4, 5]); const setB = new Set([3, 4, 5, 6, 7]); // Union — দুটোর সব মান (ES2025 নতুন method আসছে, এখন spread দিয়ে): const union = new Set([...setA, ...setB]); console.log([...union]); // → [1, 2, 3, 4, 5, 6, 7] // Intersection — উভয়তে আছে এমন: const intersection = new Set([...setA].filter(x => setB.has(x))); console.log([...intersection]); // → [3, 4, 5] // Difference — A-তে আছে কিন্তু B-তে নেই: const difference = new Set([...setA].filter(x => !setB.has(x))); console.log([...difference]); // → [1, 2]

🔷 WeakMap ও WeakSet

WeakMapWeakSet হলো Map ও Set-এর বিশেষ সংস্করণ। এদের Key হতে হবে Object। Key-এর Object অন্য কোথাও reference না থাকলে JavaScript Garbage Collector স্বয়ংক্রিয়ভাবে মেমোরি মুক্ত করে।

WeakMap vs Map পার্থক্য Comparison

বিষয় Map WeakMap
Key-এর type যেকোনো type শুধু Object
Iterable ✅ হ্যাঁ ❌ না
.size ✅ আছে ❌ নেই
Garbage Collection Reference থাকলেও মেমোরিতে Key Object সরলে auto-clean
ব্যবহার General purpose Private data, Cache
// WeakMap: const weakMap = new WeakMap(); let user1 = { id: 1, name: "করিম" }; let user2 = { id: 2, name: "রাহেলা" }; weakMap.set(user1, { role: "admin", lastLogin: "2025-01-01" }); weakMap.set(user2, { role: "viewer", lastLogin: "2025-01-05" }); console.log(weakMap.get(user1)); // → { role: "admin", lastLogin: "2025-01-01" } console.log(weakMap.has(user2)); // → true // user1-এর reference সরালে WeakMap-এ data auto-clean হবে: user1 = null; // Garbage Collector সময়মতো সরিয়ে দেবে // WeakSet: const visited = new WeakSet(); let page1 = { url: "/home" }; let page2 = { url: "/about" }; visited.add(page1); visited.add(page2); console.log(visited.has(page1)); // → true visited.delete(page1); console.log(visited.has(page1)); // → false

WeakMap-এর Practical ব্যবহার — Private Data Use Case

// WeakMap দিয়ে class-এর private data রাখা: const _privateData = new WeakMap(); class BankAccount { constructor(owner, balance) { this.owner = owner; // balance বাইরে থেকে সরাসরি access করা যাবে না: _privateData.set(this, { balance }); } deposit(amount) { const data = _privateData.get(this); data.balance += amount; } getBalance() { return _privateData.get(this).balance; } } const account = new BankAccount("করিম", 5000); account.deposit(1000); console.log(account.getBalance()); // → 6000 console.log(account.balance); // → undefined (বাইরে access নেই)
WeakMap/WeakSet কখন ব্যবহার করবে?
→ DOM element-এর সাথে data যুক্ত করতে (element মুছলে data auto-clean)।
→ Class-এর private data রাখতে।
→ Cache তৈরিতে যেখানে Object সরলে cache-ও সরবে।
সাধারণ ক্ষেত্রে Map ও Set-ই যথেষ্ট।

🔷 Structured Data — কাঠামোবদ্ধ তথ্য

Structured Data হলো নির্দিষ্ট কাঠামো মেনে সংগঠিত তথ্য। JavaScript-এ Structured Data মূলত তিন ধরনের:

ধরন কী? ব্যবহার
JSON Text-based structured format API, Config file, localStorage
ArrayBuffer Raw binary data block File, Network, WebGL (আগে আলোচিত)
SharedArrayBuffer Multiple thread-এ shared memory Web Workers, Parallel processing

SharedArrayBuffer — Shared Memory Advanced

// SharedArrayBuffer — একাধিক Worker-এর মধ্যে memory share: const sharedBuffer = new SharedArrayBuffer(4); // 4 bytes const sharedView = new Int32Array(sharedBuffer); sharedView[0] = 42; console.log(sharedView[0]); // → 42 // এই buffer অন্য Web Worker-এ পাঠালে উভয়ই একই memory দেখবে। // সাধারণ প্রজেক্টে প্রয়োজন হয় না — শুধু জানার জন্য।
সাধারণ Web Development-এ Structured Data বলতে মূলত JSON-ই বোঝায়। ArrayBuffer ও SharedArrayBuffer শুধু বিশেষ ক্ষেত্রে দরকার হয়।

🔷 JSON — JavaScript Object Notation

JSON (JavaScript Object Notation) হলো structured data সংরক্ষণ ও আদান-প্রদানের সবচেয়ে জনপ্রিয় text format। API call, Config file, localStorage — সব জায়গায় JSON ব্যবহার হয়।

JSON Format-এর নিয়ম Format

JavaScript JSON-এ সম্ভব? JSON রূপ
"হ্যালো" "হ্যালো"
42, 3.14 42, 3.14
true, false true, false
null null
{ key: "val" } ✅ (Key double quote-এ) {"key": "val"}
[1, 2, 3] [1, 2, 3]
undefined বাদ যায় বা null
function(){} বাদ যায়
Symbol() বাদ যায়
new Date() ⚠️ String হিসেবে "2025-01-01T00:00:00.000Z"
// ✅ বৈধ JSON: { "name": "করিম", "age": 25, "isStudent": true, "score": null, "hobbies": ["পড়া", "খেলা"], "address": { "city": "ঢাকা", "zip": "1216" } } // ❌ অবৈধ JSON: { name: "করিম", // Key-তে quote নেই 'city': 'ঢাকা', // Single quote ব্যবহার score: undefined, // undefined নিষিদ্ধ greet: function(){}, // Function নিষিদ্ধ // এটা comment — Comment নিষিদ্ধ "last": "item", // Trailing comma নিষিদ্ধ }

JSON.stringify() — Object → JSON String Serialize

const user = { name: "রাহেলা", age: 22, city: "ঢাকা", password: "secret123", // এটা বাদ দিতে চাই greet: function() {}, // Function — JSON-এ আসবে না token: undefined // undefined — JSON-এ আসবে না }; // মৌলিক stringify: const json = JSON.stringify(user); console.log(json); // → {"name":"রাহেলা","age":22,"city":"ঢাকা"} // সুন্দর formatting (space দিয়ে): const pretty = JSON.stringify(user, null, 2); console.log(pretty); // → { // "name": "রাহেলা", // "age": 22, // "city": "ঢাকা" // } // Replacer Array — শুধু নির্দিষ্ট key রাখো: const safe = JSON.stringify(user, ["name", "city"]); console.log(safe); // → {"name":"রাহেলা","city":"ঢাকা"} (password বাদ) // Replacer Function — নিয়ম দিয়ে ফিল্টার: const filtered = JSON.stringify(user, (key, value) => { if (key === "password") return undefined; // বাদ দাও if (typeof value === "number") return value * 1; return value; }); console.log(filtered); // → {"name":"রাহেলা","age":22,"city":"ঢাকা"}

JSON.parse() — JSON String → Object Deserialize

// মৌলিক parse: const jsonStr = '{"name":"করিম","age":25,"city":"ঢাকা"}'; const obj = JSON.parse(jsonStr); console.log(obj.name); // → করিম console.log(obj.age); // → 25 console.log(typeof obj); // → object // Reviver — parse করার সময় মান রূপান্তর: const dataStr = '{"name":"রাহেলা","score":"95","joined":"2023-01-15"}'; const data = JSON.parse(dataStr, (key, value) => { if (key === "score") return Number(value); // String → Number if (key === "joined") return new Date(value); // String → Date return value; }); console.log(data.score); // → 95 (Number, String নয়) console.log(data.joined instanceof Date); // → true // Error handling — ভুল JSON parse করলে: try { JSON.parse("{invalid json}"); } catch (error) { console.log("JSON Error:", error.message); }

JSON দিয়ে Deep Clone Trick

const original = { name: "করিম", address: { city: "ঢাকা", area: "মিরপুর" } }; // Shallow copy সমস্যা: const shallow = { ...original }; shallow.address.city = "চট্টগ্রাম"; console.log(original.address.city); // → চট্টগ্রাম ⚠️ (মূলও বদলে গেল!) // Deep copy — JSON দিয়ে: const original2 = { name: "রাহেলা", address: { city: "ঢাকা", area: "উত্তরা" } }; const deep = JSON.parse(JSON.stringify(original2)); deep.address.city = "সিলেট"; console.log(original2.address.city); // → ঢাকা ✅ (মূল অপরিবর্তিত) // আধুনিক পদ্ধতি (Node.js 17+, Modern Browser): const deep2 = structuredClone(original2); // আরও নির্ভরযোগ্য

JSON-এর সীমাবদ্ধতা Limitations

সমস্যা উদাহরণ সমাধান
Function বাদ যায় stringify({fn: () => {}}){} Function ছাড়া data রাখো
Date String হয়ে যায় parse(stringify(new Date())) → String Reviver দিয়ে new Date() করো
Circular Reference Error Object নিজেকেই reference করলে Replacer দিয়ে বাদ দাও
undefined বাদ যায় stringify({a: undefined}){} null ব্যবহার করো
Map/Set সাপোর্ট নেই Map/Set → {} হয়ে যায় Array-এ convert করো

localStorage-এ JSON ব্যবহার Practical

// localStorage শুধু String রাখতে পারে। // Object রাখতে JSON.stringify দরকার। const settings = { theme: "dark", lang: "bn", fontSize: 16 }; // সংরক্ষণ: localStorage.setItem("settings", JSON.stringify(settings)); // পড়া: const saved = JSON.parse(localStorage.getItem("settings")); console.log(saved.theme); // → dark // নেই হলে default: const raw = localStorage.getItem("missing"); const data = raw ? JSON.parse(raw) : { theme: "light" }; console.log(data.theme); // → light

🔷 Stack — LIFO কাঠামো

Stack হলো LIFO (Last In, First Out) কাঠামো। সহজ উপমা — বাসনের স্তূপ: সর্বশেষ রাখা বাসনটি সর্বপ্রথম তোলা হয়।

Operation অর্থ Array Method
push(item) Stack-এর উপরে রাখো array.push(item)
pop() উপর থেকে বের করো array.pop()
peek() উপরেরটা শুধু দেখো (বের করো না) array[array.length - 1]
isEmpty() খালি কিনা array.length === 0
// Stack Class তৈরি: class Stack { #items = []; // Private Array push(item) { this.#items.push(item); } pop() { if (this.isEmpty()) return "Stack খালি!"; return this.#items.pop(); } peek() { if (this.isEmpty()) return "Stack খালি!"; return this.#items[this.#items.length - 1]; } isEmpty() { return this.#items.length === 0; } get size() { return this.#items.length; } display() { console.log([...this.#items].reverse()); } } const stack = new Stack(); stack.push("প্রথম"); stack.push("দ্বিতীয়"); stack.push("তৃতীয়"); console.log(stack.peek()); // → তৃতীয় (উপরে আছে) console.log(stack.pop()); // → তৃতীয় (বের হলো) console.log(stack.peek()); // → দ্বিতীয় (এখন উপরে) console.log(stack.size); // → 2

Stack-এর Practical ব্যবহার — Undo/Redo Real-world

// Text Editor-এর Undo: const undoStack = []; let currentText = ""; function type(text) { undoStack.push(currentText); // আগের state সংরক্ষণ currentText += text; console.log("Current:", currentText); } function undo() { if (undoStack.length === 0) return; currentText = undoStack.pop(); // আগের state ফেরত console.log("Undo:", currentText); } type("হ্যা"); // → Current: হ্যা type("লো"); // → Current: হ্যালো type(" বিশ্ব"); // → Current: হ্যালো বিশ্ব undo(); // → Undo: হ্যালো undo(); // → Undo: হ্যা
Stack-এর বাস্তব ব্যবহার: Browser-এর Back বাটন, Text Editor-এর Undo, Function Call Stack (JavaScript নিজেই ব্যবহার করে), Brackets Matching (({[]}) সঠিক কিনা চেক করা)।

🔷 Queue — FIFO কাঠামো

Queue হলো FIFO (First In, First Out) কাঠামো। সহজ উপমা — দোকানের লাইন: যে আগে এসেছে সে আগে সেবা পাবে।

Operation অর্থ Array Method
enqueue(item) Queue-এর শেষে যোগ array.push(item)
dequeue() Queue-এর শুরু থেকে বের করো array.shift()
front() সামনেরটা শুধু দেখো array[0]
isEmpty() খালি কিনা array.length === 0
// Queue Class তৈরি: class Queue { #items = []; enqueue(item) { this.#items.push(item); // শেষে যোগ } dequeue() { if (this.isEmpty()) return "Queue খালি!"; return this.#items.shift(); // শুরু থেকে বের } front() { if (this.isEmpty()) return "Queue খালি!"; return this.#items[0]; } isEmpty() { return this.#items.length === 0; } get size() { return this.#items.length; } display() { console.log([...this.#items]); } } const queue = new Queue(); queue.enqueue("আরিফ"); // লাইনে দাঁড়াল queue.enqueue("বিথি"); // তারপর বিথি queue.enqueue("চাঁদনী"); // তারপর চাঁদনী console.log(queue.front()); // → আরিফ (সামনে আছে) console.log(queue.dequeue()); // → আরিফ (প্রথমে সেবা পেল) console.log(queue.front()); // → বিথি (এখন সামনে) console.log(queue.size); // → 2

Queue-এর Practical ব্যবহার — Task Processing Real-world

// Print Queue: class PrintQueue { #queue = []; addJob(doc) { this.#queue.push(doc); console.log(`"${doc}" print queue-এ যোগ হলো।`); } printNext() { if (this.#queue.length === 0) { console.log("Queue খালি।"); return; } const doc = this.#queue.shift(); console.log(`"${doc}" print হচ্ছে...`); } showQueue() { console.log("অপেক্ষায়:", this.#queue); } } const printer = new PrintQueue(); printer.addJob("রিপোর্ট.pdf"); printer.addJob("চিঠি.docx"); printer.addJob("ছবি.png"); printer.printNext(); // → "রিপোর্ট.pdf" print হচ্ছে... printer.showQueue(); // → অপেক্ষায়: ["চিঠি.docx", "ছবি.png"]
Queue-এর বাস্তব ব্যবহার: Print Queue, Task Scheduler, Notification System, Breadth-First Search (BFS), JavaScript-এর Event Queue (Callback Queue)।

🔷 দ্রুত রেফারেন্স — JavaScript Data Structures

কোন Data Structure কখন ব্যবহার করবে? Decision Guide

পরিস্থিতি সেরা পছন্দ কারণ
তালিকা রাখতে হবে, ক্রম গুরুত্বপূর্ণ Array Index-ভিত্তিক, সহজ iteration
নামযুক্ত তথ্য রাখতে হবে Object Dot notation, JSON-friendly
Key যেকোনো type হবে Map Object, Number, Function — যেকোনো Key
Duplicate বাদ দিতে হবে Set Unique মান guarantee করে
মেমোরি leak এড়াতে private data WeakMap Garbage Collection সাপোর্ট করে
Object visit করা হয়েছে কিনা ট্র্যাক WeakSet Object Garbage Collected হলে auto-remove
Undo/Redo, Function call tracking Stack LIFO — শেষেরটা আগে দরকার
Task queue, Notification Queue FIFO — আগেরটা আগে প্রক্রিয়া

Array-এর গুরুত্বপূর্ণ Methods এক নজরে Array

ধরন Methods
Mutating (মূল বদলায়) push, pop, shift, unshift, splice, sort, reverse, fill
Non-Mutating (নতুন ফেরত) slice, concat, join, indexOf, includes, flat, toSorted, toReversed
Iterative (প্রতিটিতে কাজ) forEach, map, filter, reduce, find, findIndex, some, every, flatMap
Static Array.isArray(), Array.from(), Array.of()

Map ও Set-এর Methods এক নজরে Map / Set

Method Map Set
যোগ করা .set(key, val) .add(val)
মান পড়া .get(key) — (iteration দিয়ে)
আছে কিনা .has(key) .has(val)
মুছে ফেলা .delete(key) .delete(val)
সব মোছা .clear() .clear()
সংখ্যা .size .size

🧠 নিজেকে যাচাই করো

1. Array-এর push() কী করে?

2. Object-এ property access কীভাবে?

3. Array.map() কী করে?

✏️ Task — এখন তুমি করো

তোমার skills array তৈরি করো। push, pop, map, filter, find ব্যবহার করো।

ধাপ 5🏗️ Real Project — Interactive Portfolio

Portfolio-এর skills ও projects Array ও Object দিয়ে manage করো।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio-এর projects array তৈরি করো। filter দিয়ে completed project দেখাও।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

⚖️ JavaScript Equality Comparisons — সম্পূর্ণ নোট

এই সেকশনে JavaScript-এর সমতা তুলনার সব পদ্ধতি — Abstract Equality (==), Strict Equality (===), SameValue (Object.is()), এবং SameValueZero — বাংলায় উদাহরণসহ আলোচনা করা হয়েছে।


🔷 Equality Comparisons কী ও কেন প্রয়োজন?

Equality Comparison হলো দুটো মান সমান কিনা তা যাচাই করার পদ্ধতি। JavaScript-এ এটি অন্য ভাষার চেয়ে জটিল — কারণ এখানে Type Coercion (type রূপান্তর) ঘটতে পারে।

সহজ উদাহরণ — "5" == 5 লিখলে JavaScript বলে true, কিন্তু "5" === 5 লিখলে বলে false। এই পার্থক্যটুকু না বুঝলেই বাগ তৈরি হয়।

তুলনার পদ্ধতি Operator / Method Type Coercion? বিশেষত্ব ES Version
Abstract Equality == ✅ হ্যাঁ Type ভিন্ন হলে convert করে তুলনা করে ES1
Strict Equality === ❌ না Type ও মান দুটোই মিলতে হবে ES3
SameValue Object.is() ❌ না NaN === NaN এবং +0 ≠ -0 সঠিকভাবে ES6
SameValueZero Map, Set, includes() ❌ না NaN সমান, কিন্তু +0 ও -0 সমান ES6

🔷 Abstract Equality — == (Loose Equality)

Abstract Equality (==)-তে দুটো মানের type ভিন্ন হলে JavaScript স্বয়ংক্রিয়ভাবে একটিকে অন্যটির type-এ রূপান্তর করে তুলনা করে। এই প্রক্রিয়াকে Type Coercion বলে।

Type Coercion-এর নিয়মাবলী Rules

তুলনা ফলাফল কারণ
"5" == 5 true String "5" → Number 5-এ convert হয়
0 == false true false → Number 0-এ convert হয়
1 == true true true → Number 1-এ convert হয়
null == undefined true বিশেষ নিয়ম — এই দুটো পরস্পর সমান
null == 0 false null শুধু undefined-এর সাথেই সমান
"" == 0 true খালি String → Number 0
"0" == false true "0" → 0, false → 0
[] == false true [] → "" → 0, false → 0
NaN == NaN false NaN কখনো নিজের সাথেও সমান নয়
// Abstract Equality (==) উদাহরণ: // ১. String vs Number: console.log("5" == 5); // → true (String → Number) console.log("05" == 5); // → true ("05" → 5) console.log("5.0" == 5); // → true ("5.0" → 5) // ২. Boolean Coercion: console.log(true == 1); // → true (true → 1) console.log(false == 0); // → true (false → 0) console.log(true == "1"); // → true (true → 1, "1" → 1) console.log(false == ""); // → true (false → 0, "" → 0) // ৩. null ও undefined বিশেষ আচরণ: console.log(null == undefined); // → true (বিশেষ নিয়ম) console.log(null == 0); // → false (null শুধু undefined-এর সাথে) console.log(null == false); // → false console.log(undefined == 0); // → false console.log(undefined == false); // → false // ৪. Object Coercion: console.log([] == 0); // → true ([] → "" → 0) console.log(["5"] == 5); // → true (["5"] → "5" → 5) console.log({} == "[object Object]"); // → true // ৫. NaN — কখনো সমান নয়: console.log(NaN == NaN); // → false ⚠️ console.log(NaN == 0); // → false console.log(NaN == false); // → false

==-এর একমাত্র ভালো ব্যবহার Use Case

// null/undefined একসাথে চেক করা — এটাই == এর একমাত্র গ্রহণযোগ্য ব্যবহার: function processValue(val) { if (val == null) { // val === null অথবা val === undefined — দুটোই ধরা পড়বে console.log("মান নেই"); return; } console.log("মান আছে:", val); } processValue(null); // → মান নেই processValue(undefined); // → মান নেই processValue(0); // → মান আছে: 0 processValue(""); // → মান আছে: // উপরেরটা এভাবেও লেখা যায়, কিন্তু বেশি verbose: if (val === null || val === undefined) { /* ... */ }
⚠️ == সাবধান: null == null চেক ছাড়া অন্য ক্ষেত্রে == ব্যবহার করলে অপ্রত্যাশিত bug তৈরি হতে পারে। সবসময় === ব্যবহার করো — ESLint-ও এটাই suggest করে।

🔷 Strict Equality — === (সবচেয়ে বেশি ব্যবহৃত)

Strict Equality (===)-তে কোনো Type Coercion হয় না। তুলনা করা দুটো মানের type ও মান — উভয়ই হুবহু মিলতে হবে। এটিই সবচেয়ে নিরাপদ ও প্রস্তাবিত পদ্ধতি।

Strict Equality কীভাবে কাজ করে? Algorithm

তুলনা ফলাফল কারণ
"5" === 5 false Type ভিন্ন (String vs Number)
5 === 5 true Type ও মান একই
true === 1 false Type ভিন্ন (Boolean vs Number)
null === undefined false Type ভিন্ন
null === null true Type ও মান একই
NaN === NaN false NaN কখনো নিজের সাথেও সমান নয় ⚠️
+0 === -0 true === এ +0 ও -0 সমান (Object.is-এ নয়)
[] === [] false দুটো আলাদা Object reference
{} === {} false দুটো আলাদা Object reference

Primitive vs Reference Equality গুরুত্বপূর্ণ

// ===== Primitive Equality — মান তুলনা ===== console.log(42 === 42); // → true console.log("বাংলা" === "বাংলা"); // → true console.log(true === true); // → true console.log(null === null); // → true console.log(undefined === undefined); // → true // ===== Reference Equality — ঠিকানা তুলনা ===== // Array: const arr1 = [1, 2, 3]; const arr2 = [1, 2, 3]; const arr3 = arr1; // একই reference console.log(arr1 === arr2); // → false ⚠️ (আলাদা object, মান একই হলেও) console.log(arr1 === arr3); // → true ✅ (একই reference) // Object: const obj1 = { name: "করিম" }; const obj2 = { name: "করিম" }; const obj3 = obj1; console.log(obj1 === obj2); // → false ⚠️ console.log(obj1 === obj3); // → true ✅ // Function: const fn1 = () => {}; const fn2 = () => {}; console.log(fn1 === fn2); // → false ⚠️ (আলাদা function object)

ব্যবহারিক উদাহরণ Practical

// ১. Type চেক করে তারপর কাজ করা: function greet(name) { if (typeof name !== "string") { throw new Error("নাম অবশ্যই String হতে হবে"); } return `আস-সালামু আলাইকুম, ${name}!`; } // ২. Switch statement — সবসময় === ব্যবহার করে: const day = 3; switch (day) { case 1: console.log("শনিবার"); break; case 2: console.log("রবিবার"); break; case 3: console.log("সোমবার"); break; // → সোমবার default: console.log("অজানা দিন"); } // ৩. Object-এর মান তুলনা (JSON দিয়ে — সীমাবদ্ধতা আছে): const a = { name: "রাহেলা", score: 92 }; const b = { name: "রাহেলা", score: 92 }; // ভুল পদ্ধতি: console.log(a === b); // → false (reference আলাদা) // কাজ চালানোর মতো পদ্ধতি (Function/undefined/Date নেই হলে): console.log(JSON.stringify(a) === JSON.stringify(b)); // → true // সঠিক পদ্ধতি (Deep Equal Library বা নিজে লেখা): function deepEqual(x, y) { if (x === y) return true; if (typeof x !== "object" || typeof y !== "object") return false; if (x === null || y === null) return false; const keysX = Object.keys(x); const keysY = Object.keys(y); if (keysX.length !== keysY.length) return false; return keysX.every(key => deepEqual(x[key], y[key])); } console.log(deepEqual(a, b)); // → true ✅
সোনার নিয়ম: সবসময় === ব্যবহার করো। শুধুমাত্র null/undefined একসাথে চেক করতে == null ব্যবহার করা যেতে পারে। ESLint-এর eqeqeq rule চালু রাখলে == ব্যবহার করলে সতর্কবার্তা দেবে।

🔷 SameValue — Object.is()

SameValue (Object.is()) হলো ES6-এর সবচেয়ে precise equality পদ্ধতি। এটি ===-এর মতোই কাজ করে, শুধু দুটো বিশেষ ক্ষেত্রে পার্থক্য আছে।

=== বনাম Object.is() পার্থক্য Comparison

তুলনা === ফলাফল Object.is() ফলাফল পার্থক্য আছে?
NaN, NaN false true ✅ হ্যাঁ
+0, -0 true false ✅ হ্যাঁ
5, 5 true true ❌ একই
"ক", "ক" true true ❌ একই
null, null true true ❌ একই
[], [] false false ❌ একই

Object.is() ব্যবহার Usage

// ১. NaN চেক করা — Object.is() সবচেয়ে নির্ভরযোগ্য: console.log(NaN === NaN); // → false ⚠️ (বিভ্রান্তিকর!) console.log(Object.is(NaN, NaN)); // → true ✅ // NaN চেক করার অন্য পদ্ধতিগুলো: console.log(Number.isNaN(NaN)); // → true ✅ (সবচেয়ে প্রস্তাবিত) console.log(isNaN("hello")); // → true ⚠️ (String-ও true দেয়!) console.log(Number.isNaN("hello")); // → false ✅ (শুধু NaN-এর জন্য true) // ২. +0 ও -0 পার্থক্য: console.log(+0 === -0); // → true ⚠️ (=== পার্থক্য বোঝে না) console.log(Object.is(+0, -0)); // → false ✅ (সঠিক) console.log(Object.is(+0, +0)); // → true console.log(Object.is(-0, -0)); // → true // ৩. সব ক্ষেত্রে === এর মতো: console.log(Object.is(42, 42)); // → true console.log(Object.is("বাংলা", "বাংলা")); // → true console.log(Object.is(null, null)); // → true console.log(Object.is(undefined, undefined)); // → true console.log(Object.is(true, true)); // → true // Object.is() বাস্তবায়ন (অনুধাবনের জন্য): function sameValue(x, y) { if (x !== x) return y !== y; // NaN চেক (NaN !== NaN) if (x === 0 && y === 0) return 1/x === 1/y; // +0 vs -0 (1/+0=Infinity, 1/-0=-Infinity) return x === y; }

কখন Object.is() দরকার হয়? Use Cases

// ক. গণিতের NaN পরীক্ষা: function safeDivide(a, b) { const result = a / b; if (Object.is(result, NaN)) { return 0; // অথবা error throw } return result; } // খ. শূন্যের চিহ্ন (sign) গুরুত্বপূর্ণ হলে: function checkSign(n) { if (Object.is(n, -0)) return "ঋণাত্মক শূন্য"; if (Object.is(n, +0)) return "ধনাত্মক শূন্য"; return n > 0 ? "ধনাত্মক" : "ঋণাত্মক"; } console.log(checkSign(-0)); // → ঋণাত্মক শূন্য console.log(checkSign(+0)); // → ধনাত্মক শূন্য // গ. React-এর useState — পরিবর্তন হয়েছে কিনা যাচাই (Fiber-এ Object.is ব্যবহার হয়): // React internally does: if (Object.is(prevState, nextState)) return; // no re-render

🔷 SameValueZero — Map, Set ও includes()-এর ভেতরের algorithm

SameValueZero হলো JavaScript-এর অভ্যন্তরীণ algorithm। এটি সরাসরি call করা যায় না, তবে Map, Set, Array.prototype.includes() এবং String.prototype.includes() এই algorithm ব্যবহার করে।

চার Equality পদ্ধতির তুলনা Full Comparison

তুলনা == === Object.is() SameValueZero
NaN, NaN false false true true
+0, -0 true true false true
"5", 5 true false false false
null, undefined true false false false
1, 1 true true true true

SameValueZero কোথায় দেখা যায়? Examples

// ১. Set — NaN duplicate হিসেবে গণ্য হয়: const set = new Set(); set.add(NaN); set.add(NaN); // SameValueZero: NaN === NaN → duplicate → উপেক্ষিত console.log(set.size); // → 1 ✅ (NaN একটিই) console.log(set.has(NaN)); // → true ✅ // কিন্তু === দিয়ে চেক করলে: console.log(NaN === NaN); // → false ⚠️ // ২. Set — +0 ও -0 সমান: const set2 = new Set(); set2.add(+0); set2.add(-0); // SameValueZero: +0 === -0 → duplicate → উপেক্ষিত console.log(set2.size); // → 1 (+0 ও -0 সমান) // ৩. Map — NaN Key হিসেবে কাজ করে: const map = new Map(); map.set(NaN, "না-সংখ্যা"); console.log(map.get(NaN)); // → না-সংখ্যা ✅ console.log(map.has(NaN)); // → true ✅ // ৪. Array.prototype.includes() — NaN খুঁজে পায়: const arr = [1, 2, NaN, 4]; console.log(arr.includes(NaN)); // → true ✅ (SameValueZero ব্যবহার করে) console.log(arr.indexOf(NaN)); // → -1 ⚠️ (indexOf === ব্যবহার করে, তাই NaN খোঁজে না) // ৫. indexOf vs includes পার্থক্য: const data = [1, undefined, null, NaN]; console.log(data.includes(NaN)); // → true (SameValueZero) console.log(data.indexOf(NaN)); // → -1 (Strict Equality)
মনে রাখো: Array-এ NaN খুঁজতে সবসময় .includes() ব্যবহার করো — .indexOf() NaN খুঁজে পায় না। অথবা Number.isNaN() দিয়ে নিজে চেক করো।

🔷 Type Coercion — স্বয়ংক্রিয় type রূপান্তর

Type Coercion হলো JavaScript-এর স্বয়ংক্রিয় type রূপান্তর। দুই ধরনের Coercion আছে — Implicit (JavaScript নিজে করে) ও Explicit (প্রোগ্রামার নিজে করে)।

Falsy ও Truthy মান Boolean Context

মান Boolean রূপান্তর ধরন
false false Falsy
0, -0, 0n false Falsy
"", '', `` false Falsy (খালি String)
null false Falsy
undefined false Falsy
NaN false Falsy
1, -1, 0.5 true Truthy
"0", " ", "false" true Truthy (খালি নয় এমন String)
[], {} true Truthy (খালি হলেও!)
যেকোনো function true Truthy
// Falsy মান যাচাই: const values = [false, 0, "", null, undefined, NaN]; values.forEach(v => { console.log(`${String(v)} → ${Boolean(v)}`); }); // → false → false // → 0 → false // → → false (খালি string) // → null → false // → undefined → false // → NaN → false // সাধারণ ভুল — খালি Array ও Object truthy: if ([]) console.log("খালি Array truthy!"); // → খালি Array truthy! ✅ if ({}) console.log("খালি Object truthy!"); // → খালি Object truthy! ✅ // সঠিকভাবে Array empty চেক: const arr = []; if (arr.length === 0) console.log("Array খালি"); // → Array খালি ✅ // !! দিয়ে Boolean রূপান্তর (Explicit): console.log(!!0); // → false console.log(!!"হ্যালো"); // → true console.log(!!null); // → false console.log(!![]); // → true ⚠️

Implicit Coercion-এর বিপদজনক উদাহরণ সাবধান

// + অপারেটর: String থাকলে concatenation, না থাকলে addition: console.log(1 + "2"); // → "12" (Number + String = String!) console.log("3" - 1); // → 2 (String - Number = Number) console.log("3" * "2"); // → 6 (String * String = Number) console.log(true + true); // → 2 (true=1, 1+1=2) console.log(true + false); // → 1 console.log([] + []); // → "" ([] → "", "" + "" = "") console.log([] + {}); // → "[object Object]" console.log({} + []); // → "[object Object]" অথবা 0 (context-এ নির্ভর) // বিখ্যাত JavaScript বিভ্রান্তি: console.log(+""); // → 0 (String → Number) console.log(+true); // → 1 console.log(+false); // → 0 console.log(+null); // → 0 console.log(+undefined); // → NaN console.log(+[]); // → 0 ([] → "" → 0) console.log(+{}); // → NaN // এড়ানোর পদ্ধতি — সবসময় Explicit Coercion করো: const input = "5"; const num = Number(input); // ✅ স্পষ্ট ও নিরাপদ const num2 = parseInt(input, 10); // ✅ পূর্ণসংখ্যার জন্য

🔷 Equality-র বিশেষ ক্ষেত্র — Edge Cases

NaN — "Not a Number"-এর বিশেষ আচরণ Edge Case

// NaN কোথা থেকে আসে: console.log(0 / 0); // → NaN console.log(Math.sqrt(-1)); // → NaN console.log(parseInt("abc")); // → NaN console.log(Number("xyz")); // → NaN console.log(Infinity - Infinity); // → NaN // NaN-এর বিশেষ আচরণ: console.log(NaN === NaN); // → false ⚠️ (JavaScript-এর বিখ্যাত quirk) console.log(NaN == NaN); // → false ⚠️ console.log(NaN !== NaN); // → true // NaN চেক করার সঠিক পদ্ধতিগুলো: const n = NaN; console.log(Number.isNaN(n)); // → true ✅ (সবচেয়ে ভালো) console.log(Object.is(n, NaN)); // → true ✅ console.log(n !== n); // → true ✅ (পুরানো trick) console.log(isNaN(n)); // → true ⚠️ (কিন্তু isNaN("abc") ও true!) console.log(isNaN("abc")); // → true ⚠️ (বিভ্রান্তিকর) console.log(Number.isNaN("abc")); // → false ✅ (সঠিক — শুধু NaN-এর জন্য)

null ও undefined-এর তুলনা null / undefined

// null ও undefined-এর পার্থক্য: console.log(typeof null); // → "object" ⚠️ (JavaScript-এর পুরানো bug!) console.log(typeof undefined); // → "undefined" // Equality তুলনা: console.log(null == null); // → true console.log(undefined == undefined); // → true console.log(null == undefined); // → true (Abstract Equality-র বিশেষ নিয়ম) console.log(null === undefined); // → false (Type আলাদা) console.log(Object.is(null, undefined)); // → false // null ও অন্য মানের সাথে: console.log(null == 0); // → false console.log(null == ""); // → false console.log(null == false); // → false console.log(null > 0); // → false console.log(null < 0); // → false console.log(null==0); // → false console.log(null>= 0); // → true ⚠️ (তুলনায় null → 0!) // সঠিক চেক: function isNullish(val) { return val === null || val === undefined; // অথবা: return val == null; (== null এর একমাত্র ভালো ব্যবহার) } // Nullish Coalescing (??) — null বা undefined হলে default: const name = null ?? "অজানা"; console.log(name); // → অজানা const score = 0 ?? 100; // 0 nullish নয়! console.log(score); // → 0 ✅ (|| হলে 100 দিত — পার্থক্য জানো)

Object ও Array তুলনার সঠিক পদ্ধতি Deep Equal

// ===== Reference Equality ===== const arr1 = [1, 2, 3]; const arr2 = arr1; // একই reference arr2.push(4); console.log(arr1); // → [1, 2, 3, 4] ⚠️ (arr1 ও পরিবর্তিত!) // ===== Shallow vs Deep Copy ===== const original = { a: 1, b: { c: 2 } }; const shallow = { ...original }; // Shallow copy const deep = JSON.parse(JSON.stringify(original)); // Deep copy shallow.b.c = 99; console.log(original.b.c); // → 99 ⚠️ (shallow copy-তে nested পরিবর্তিত) deep.b.c = 77; console.log(original.b.c); // → 99 ✅ (deep copy-তে মূল অপরিবর্তিত) // ===== structuredClone() — আধুনিক Deep Copy ===== const obj = { x: 1, nested: { y: 2 }, arr: [1, 2, 3] }; const clone = structuredClone(obj); // Node.js 17+, Modern Browser clone.nested.y = 999; console.log(obj.nested.y); // → 2 ✅ // ===== Primitive Wrapper Object ===== const str1 = "হ্যালো"; // Primitive String const str2 = new String("হ্যালো"); // String Object (এড়িয়ে চলো!) console.log(str1 === "হ্যালো"); // → true console.log(str2 === "হ্যালো"); // → false ⚠️ (Object vs Primitive) console.log(str2.valueOf() === "হ্যালো"); // → true

🔷 Relational Comparison — <, >, <=, >=

Relational Operators দুটো মানের মধ্যে ছোট-বড় সম্পর্ক নির্ণয় করে। Type Coercion এখানেও প্রযোজ্য।

// Number তুলনা — স্বাভাবিক: console.log(5 > 3); // → true console.log(10 <= 10); // → true // String তুলনা — Unicode Code Point অনুযায়ী: console.log("b"> "a"); // → true ("b" = 98, "a" = 97) console.log("B" < "a" ); // → true ("B"=66, "a"=97 — uppercase আগে!) console.log("বাংলা"> "আরবি"); // → Unicode অনুযায়ী // Mixed type — Number-এ convert: console.log("5" > 3); // → true ("5" → 5 > 3) console.log("10" > "9"); // → false ⚠️ ("1" < "9" — String comparison!) console.log(10> "9"); // → true (Number comparison) // null ও undefined: console.log(null > 0); // → false console.log(null >= 0); // → true ⚠️ (null → 0) console.log(null < 1); // → true console.log(undefined> 0); // → false (undefined → NaN) console.log(undefined < 0); // → false (undefined → NaN) // String সঠিক sort করতে localeCompare(): const cities=["ঢাকা", "চট্টগ্রাম" , "সিলেট" , "বরিশাল" ]; cities.sort((a, b)=> a.localeCompare(b, "bn")); console.log(cities); // বাংলা বর্ণানুক্রম অনুযায়ী

🔷 দ্রুত রেফারেন্স — JavaScript Equality Comparisons

কোন Equality Method কখন ব্যবহার করবে? Decision Guide

পরিস্থিতি সেরা পছন্দ কারণ
সাধারণ সব তুলনা === Type-safe, নিরাপদ, প্রস্তাবিত
null বা undefined একসাথে চেক == null দুটোই ধরা পড়ে, সংক্ষিপ্ত
NaN কিনা চেক Number.isNaN() শুধু NaN-এর জন্য true, নির্ভরযোগ্য
+0 ও -0 আলাদা করতে Object.is() +0 ও -0 সঠিকভাবে আলাদা করে
Array-এ NaN খোঁজা .includes() SameValueZero — NaN খুঁজে পায়
Object / Array-এর মান তুলনা Custom deepEqual / structuredClone === শুধু reference তুলনা করে
String তুলনা (বাংলা/locale) .localeCompare() ভাষাভিত্তিক সঠিক তুলনা করে

চার Equality পদ্ধতির সারসংক্ষেপ Summary

পদ্ধতি Type Coercion NaN == NaN +0 == -0 ব্যবহার
== ✅ হ্যাঁ false true শুধু == null
=== ❌ না false true সাধারণ সব ক্ষেত্রে ✅
Object.is() ❌ না true ✅ false ✅ NaN ও ±0 সংক্রান্ত বিশেষ ক্ষেত্রে
SameValueZero ❌ না true ✅ true Map, Set, includes() — অভ্যন্তরীণ

সাধারণ ভুল ও সমাধান Common Mistakes

ভুল কোড সমস্যা সঠিক কোড
if (x == true) Type Coercion, অপ্রত্যাশিত if (x === true) বা if (x)
if (val == undefined) null চেক হয় না (=== হলে) if (val == null) উভয়ের জন্য
if (isNaN(val)) String-এও true দেয় if (Number.isNaN(val))
arr.indexOf(NaN) NaN খোঁজে পায় না (-1) arr.includes(NaN)
obj1 === obj2 Reference তুলনা, মান নয় JSON.stringify(o1) === JSON.stringify(o2) বা deepEqual
typeof null === "null" typeof null === "object" (bug!) val === null

🧠 নিজেকে যাচাই করো

1. === ও == পার্থক্য?

2. '5' == 5?

3. '5' === 5?

✏️ Task — এখন তুমি করো

console-এ test করো: '5'==5, '5'===5, null==undefined, null===undefined।

ধাপ 6🏗️ Real Project — Interactive Portfolio

Portfolio login form বানাও — equality দিয়ে validate করো।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio login form-এ === দিয়ে validate করো।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

🔁 JavaScript Loops and Iterations — সম্পূর্ণ নোট

এই সেকশনে JavaScript-এর সব ধরনের Loop — for, while, do...while, for...in, for...of, এবং Iterators ও Generators — বাংলায় উদাহরণসহ আলোচনা করা হয়েছে।


🔷 Loops কী ও কেন প্রয়োজন?

Loop হলো একটি কোড-ব্লক বারবার চালানোর পদ্ধতি। যখন একই কাজ নির্দিষ্ট সংখ্যকবার বা কোনো শর্ত পূরণ না হওয়া পর্যন্ত করতে হয় — তখন Loop ব্যবহার হয়।

সহজ উদাহরণ — একটি ক্লাসের ৪০ জন ছাত্রের রোল নম্বর প্রিন্ট করতে ৪০টি আলাদা লাইন না লিখে মাত্র একটি Loop দিয়েই কাজ হয়।

Loop কখন ব্যবহার করবে? বিশেষত্ব ES Version
for কতবার চলবে আগে থেকে জানা থাকলে Counter-controlled, সবচেয়ে বেশি ব্যবহৃত ES1
while শর্ত পূরণ না হওয়া পর্যন্ত চলবে Entry-controlled — আগে শর্ত চেক ES1
do...while কমপক্ষে একবার চালাতেই হবে Exit-controlled — পরে শর্ত চেক ES1
for...in Object-এর Key-এ iterate করতে Enumerable property iterate করে ES1
for...of Iterable-এর Value-এ iterate করতে Array, String, Map, Set সবকিছুতে ES6
for await...of Async Iterable-এ iterate করতে Promise, Stream, Async Generator ES2018

🔷 for Loop — Counter-Controlled Loop

for Loop-এ তিনটি অংশ থাকে — initialization (শুরু), condition (শর্ত), এবং update (পরিবর্তন)। কতবার চলবে আগে থেকে জানা থাকলে এটাই সেরা পছন্দ।

for Loop-এর গঠন ও ব্যবহার Syntax

// গঠন: // for (initialization; condition; update) { body } // ১. সাধারণ for loop — ১ থেকে ৫: for (let i = 1; i <= 5; i++) { console.log(i); // → 1, 2, 3, 4, 5 } // ২. Array iterate — সাধারণ পদ্ধতি: const fruits=["আম", "কলা" , "লিচু" , "পেয়ারা" ]; for (let i=0; i < fruits.length; i++) { console.log(`${i + 1}. ${fruits[i]}`); } // → 1. আম // → 2. কলা // → 3. লিচু // → 4. পেয়ারা // ৩. উল্টো দিকে (Reverse): for (let i=fruits.length - 1; i>= 0; i--) { console.log(fruits[i]); } // → পেয়ারা, লিচু, কলা, আম // ৪. Step — প্রতিবার ২ করে বাড়ানো: for (let i = 0; i <= 10; i +=2) { console.log(i); // → 0, 2, 4, 6, 8, 10 } // ৫. Multiple variable: for (let i=0, j=10; i < j; i++, j--) { console.log(i, j); // → 0 10, 1 9, 2 8, 3 7, 4 6 }

Nested for Loop — 2D Array ও Matrix Nested

// গুণের নামতা: for (let i = 1; i <= 3; i++) { for (let j=1; j <=3; j++) { console.log(`${i} × ${j}=${i * j}`); } } // → 1×1=1, 1×2=2, 1×3=3 // → 2×1=2, 2×2=4, 2×3=6 // → 3×1=3, 3×2=6, 3×3=9 // 2D Array iterate: const matrix=[ [1, 2, 3], [4, 5, 6], [7, 8, 9], ]; for (let row=0; row < matrix.length; row++) { for (let col=0; col < matrix[row].length; col++) { process.stdout.write(matrix[row][col] + " " ); } console.log(); // নতুন লাইন } // → 1 2 3 // → 4 5 6 // → 7 8 9 // ছাত্রদের সাপ্তাহিক নম্বর তালিকা: const scores=[ ["করিম", 85, 90, 78], ["রাহেলা", 92, 88, 95], ["সজল", 70, 65, 80], ]; for (let i=0; i < scores.length; i++) { const [name, ...marks]=scores[i]; const avg=marks.reduce((a, b)=> a + b, 0) / marks.length; console.log(`${name}: গড় = ${avg.toFixed(1)}`); } // → করিম: গড় = 84.3 // → রাহেলা: গড় = 91.7 // → সজল: গড় = 71.7

for Loop-এর অংশ বাদ দেওয়া Flexible

// Initialization বাদ: let i = 0; for (; i < 3; i++) { console.log(i); // → 0, 1, 2 } // Update বাদ (body-তে update): for (let j=0; j < 3;) { console.log(j); j++; // body-তে update } // সব বাদ=Infinite Loop (break দিয়ে বের হতে হবে): for (;;) { console.log("চলছে..."); break; // না দিলে অনন্তকাল চলবে! }
⚠️ Performance টিপ: Loop-এর condition-এ arr.length বারবার গণনা না করে একবার variable-এ রেখে দাও: const len = arr.length; — তারপর i < len ব্যবহার করো। বড় Array-এ পার্থক্য অনুভব করা যায়।

🔷 while Loop — Entry-Controlled Loop

while Loop-এ শুধু একটি শর্ত থাকে। শর্ত true থাকা পর্যন্ত loop চলতে থাকে। এটি Entry-controlled — প্রতিবার body চালানোর আগে শর্ত চেক হয়।

while Loop-এর গঠন ও ব্যবহার Syntax

// গঠন: // while (condition) { body } // ১. সাধারণ while: let count = 1; while (count <= 5) { console.log(count); // → 1, 2, 3, 4, 5 count++; } // ২. User Input Simulation — সঠিক পাসওয়ার্ড না দেওয়া পর্যন্ত: const correctPassword="বাংলা123" ; let attempts=["ভুল", "আরেকটা" , "বাংলা123" ]; // simulation let idx=0; while (attempts[idx] !==correctPassword) { console.log(`"${attempts[idx]}" — ভুল পাসওয়ার্ড, আবার চেষ্টা করো।`); idx++; } console.log("লগইন সফল!"); // → লগইন সফল! // ৩. সংখ্যার অঙ্কের যোগফল: let number=12345; let sum=0; while (number> 0) { sum += number % 10; // শেষ অঙ্ক যোগ number = Math.floor(number / 10); // শেষ অঙ্ক বাদ } console.log(sum); // → 15 (1+2+3+4+5) // ৪. Array থেকে ডেটা processing — শর্তসাপেক্ষ: const tasks = ["রিপোর্ট", "মিটিং", "কোডিং", null, "ডিজাইন"]; let taskIdx = 0; while (taskIdx < tasks.length && tasks[taskIdx] !==null) { console.log(`কাজ: ${tasks[taskIdx]}`); taskIdx++; } // → কাজ: রিপোর্ট, মিটিং, কোডিং (null-এ থেমে যায়)

Infinite Loop ও নিরাপদ বের হওয়া সাবধান

// Infinite Loop-এর সাধারণ কারণ — update ভুলে যাওয়া: let x = 0; while (x < 5) { console.log(x); // ⚠️ x++ ভুলে গেলে অনন্তকাল চলবে! x++; // ✅ অবশ্যই থাকতে হবে } // Safety counter দিয়ে Infinite Loop রোধ: let maxTries=1000; let found=false; while (!found && maxTries> 0) { // কিছু কাজ... maxTries--; if (maxTries === 0) console.log("সীমা শেষ, বের হচ্ছি"); }

🔷 do...while Loop — Exit-Controlled Loop

do...while Loop হলো Exit-controlled Loop। শর্ত false হলেও body কমপক্ষে একবার চালু হবেই। এটিই while-এর সাথে একমাত্র পার্থক্য।

while বনাম do...while পার্থক্য Comparison

বিষয় while do...while
শর্ত চেক Body-র আগে (Entry) Body-র পরে (Exit)
শর্ত প্রথমেই false একবারও চলে না একবার চলে তারপর থামে
সর্বনিম্ন execution ০ বার ১ বার
সেরা ব্যবহার কতবার চলবে অনিশ্চিত কমপক্ষে একবার চালাতেই হবে
// গঠন: // do { body } while (condition); // ১. সাধারণ do...while: let num = 1; do { console.log(num); // → 1, 2, 3, 4, 5 num++; } while (num <= 5); // ২. শর্ত প্রথমেই false — তবুও একবার চলে: let n=10; do { console.log("একবার চলল:", n); // → একবার চলল: 10 n++; } while (n < 5); // n=10> 5, কিন্তু একবার চলে গেছে while (n < 5) { console.log("while চলল"); // → কখনো চলবে না n++; } // ৩. মেনু সিমুলেশন — কমপক্ষে একবার মেনু দেখাতেই হবে: const menu=["১. নতুন ফাইল", "২. খোলা" , "৩. সংরক্ষণ" , "৪. বের হও" ]; let choice; let choices=[1, 2, 4]; // simulation — ব্যবহারকারীর পছন্দ let choiceIdx=0; do { console.log("\n--- মেনু ---"); menu.forEach(item=> console.log(item)); choice = choices[choiceIdx++]; console.log(`পছন্দ: ${choice}`); } while (choice !== 4); console.log("প্রোগ্রাম বন্ধ হচ্ছে।"); // ৪. Input Validation Pattern: let input; let inputs = ["", "ab", "করিম"]; // simulation let inputIdx = 0; do { input = inputs[inputIdx++]; if (!input || input.length < 3) { console.log("কমপক্ষে ৩ অক্ষরের নাম দাও।"); } } while (!input || input.length < 3); console.log(`নাম গ্রহণ করা হয়েছে: ${input}`); // → নাম গ্রহণ: করিম

🔷 for...in Loop — Object-এর Key iterate করা

for...in Loop Object-এর সব enumerable property-র Key-এ iterate করে। Array-এও কাজ করে কিন্তু সেখানে for...of বা forEach ব্যবহার করা ভালো।

for...in-এর গঠন ও ব্যবহার Syntax

// গঠন: // for (const key in object) { body } // ১. Object-এর Key iterate: const student = { name: "রাহেলা", age: 20, score: 92, city: "ঢাকা", }; for (const key in student) { console.log(`${key}: ${student[key]}`); } // → name: রাহেলা // → age: 20 // → score: 92 // → city: ঢাকা // ২. Dynamic Object processing: const grades = { বাংলা: 85, গণিত: 92, ইংরেজি: 78, বিজ্ঞান: 88 }; let total = 0; let count = 0; for (const subject in grades) { total += grades[subject]; count++; console.log(`${subject}: ${grades[subject]}`); } console.log(`গড়: ${(total / count).toFixed(1)}`); // → গড়: 85.8 // ৩. Nested Object iterate: const inventory = { চাল: { price: 65, qty: 100 }, ডাল: { price: 120, qty: 50 }, তেল: { price: 180, qty: 30 }, }; for (const item in inventory) { const { price, qty } = inventory[item]; console.log(`${item}: দাম=${price}, পরিমাণ=${qty}, মোট=${price * qty}`); } // → চাল: দাম=65, পরিমাণ=100, মোট=6500 // → ডাল: দাম=120, পরিমাণ=50, মোট=6000 // → তেল: দাম=180, পরিমাণ=30, মোট=5400

Prototype Chain সমস্যা ও সমাধান সাবধান

// সমস্যা — Prototype-এর property: function Animal(name) { this.name = name; } Animal.prototype.type = "প্রাণী"; // Prototype-এ property const cat = new Animal("বিড়াল"); cat.sound = "মিঁয়াও"; for (const key in cat) { console.log(key); // → name, sound, type ⚠️ (type prototype থেকে এসেছে!) } // সমাধান — hasOwnProperty চেক: for (const key in cat) { if (Object.hasOwn(cat, key)) { // শুধু নিজের property console.log(`${key}: ${cat[key]}`); } } // → name: বিড়াল // → sound: মিঁয়াও // Array-এ for...in এড়িয়ে চলো: const arr = ["ক", "খ", "গ"]; for (const i in arr) { console.log(typeof i, i); // → string "0", string "1", string "2" ⚠️ // Index String হিসেবে আসে — সমস্যা হতে পারে! }
for...in কখন ব্যবহার করবে:
→ Object-এর সব Key দেখতে বা সব property নিয়ে কাজ করতে।
→ Object-কে dynamically process করতে।
→ Array-এ কখনো ব্যবহার করো না — সেখানে for...of বা forEach ব্যবহার করো।

🔷 for...of Loop — Iterable-এর Value iterate করা

for...of Loop হলো ES6-এর সেরা সংযোজন। এটি যেকোনো Iterable-এর মান সরাসরি পায় — index বা key-এর ঝামেলা নেই। Array, String, Map, Set, NodeList — সবকিছুতে কাজ করে।

for...in বনাম for...of পার্থক্য Comparison

বিষয় for...in for...of
কী দেয়? Key (property name) Value (মান)
Object-এ ✅ কাজ করে ❌ Plain Object-এ নয়
Array-এ ⚠️ String index দেয় ✅ মান সরাসরি
String-এ ⚠️ index দেয় ✅ character সরাসরি
Map / Set-এ ❌ কাজ করে না ✅ কাজ করে
Prototype chain ⚠️ আসতে পারে ✅ আসে না

for...of-এর ব্যবহার Usage

// গঠন: // for (const value of iterable) { body } // ১. Array: const cities = ["ঢাকা", "চট্টগ্রাম", "সিলেট", "রাজশাহী"]; for (const city of cities) { console.log(city); // → ঢাকা, চট্টগ্রাম, সিলেট, রাজশাহী } // ২. Array-এ index ও value দুটোই — entries() দিয়ে: for (const [index, city] of cities.entries()) { console.log(`${index + 1}. ${city}`); } // → 1. ঢাকা // → 2. চট্টগ্রাম // → 3. সিলেট // → 4. রাজশাহী // ৩. String — প্রতিটি character: const word = "বাংলাদেশ"; for (const char of word) { console.log(char); // → ব, া, ং, ল, া, দ, ে, শ } // ৪. Map iterate: const scores = new Map([ ["করিম", 85], ["রাহেলা", 92], ["সজল", 78], ]); for (const [name, score] of scores) { console.log(`${name}: ${score}`); } // → করিম: 85 // → রাহেলা: 92 // → সজল: 78 // ৫. Set iterate: const uniqueTags = new Set(["js", "css", "html", "js", "css"]); for (const tag of uniqueTags) { console.log(tag); // → js, css, html (duplicate নেই) } // ৬. Object-এ for...of — entries() দিয়ে: const product = { name: "চাল", price: 65, qty: 100 }; for (const [key, value] of Object.entries(product)) { console.log(`${key}: ${value}`); } // → name: চাল // → price: 65 // → qty: 100

for...of-এর বিশেষ সুবিধা Advanced

// ১. NodeList (DOM) iterate: // const buttons = document.querySelectorAll("button"); // for (const btn of buttons) { // btn.addEventListener("click", () => console.log(btn.textContent)); // } // ২. Arguments object: function sum() { let total = 0; for (const num of arguments) { total += num; } return total; } console.log(sum(1, 2, 3, 4, 5)); // → 15 // ৩. Generator function-এর মান পাওয়া (পরে বিস্তারিত): function* countdown(start) { while (start > 0) { yield start--; } } for (const n of countdown(5)) { console.log(n); // → 5, 4, 3, 2, 1 } // ৪. for await...of — Async Iterable (API calls): async function fetchAllUsers(ids) { for await (const id of ids) { // const user = await fetchUser(id); // প্রতিটি await করে console.log(`User ${id} লোড হলো`); } }

🔷 Loop Control — break, continue ও label

Loop চলাকালীন তার আচরণ নিয়ন্ত্রণ করতে তিনটি keyword আছে — break (সম্পূর্ণ বের হওয়া), continue (এড়িয়ে পরেরটায় যাওয়া), এবং label (nested loop-এ নির্দিষ্ট loop ধরা)।

break ও continue Control

Keyword কাজ কোথায় ব্যবহার
break Loop বা switch সম্পূর্ণ বন্ধ করে for, while, do...while, switch
continue বর্তমান iteration বাদ দিয়ে পরেরটায় যায় for, while, do...while
label + break Nested loop-এর নির্দিষ্ট loop বন্ধ করে Nested loop
label + continue Nested loop-এর নির্দিষ্ট loop-এর পরের iteration-এ যায় Nested loop
// ===== break ===== // ১. প্রথম ঋণাত্মক সংখ্যা খুঁজে বের হওয়া: const numbers = [5, 8, 3, -2, 7, -4, 1]; let firstNegative = null; for (const num of numbers) { if (num < 0) { firstNegative=num; break; // খুঁজে পেয়েছি, আর দরকার নেই } } console.log(firstNegative); // → -2 // ২. while + break দিয়ে নিরাপদ Infinite Loop: let attempts=0; while (true) { attempts++; if (attempts>= 3) break; // তিনটার বেশি নয় } console.log(`${attempts} বার চেষ্টা হলো`); // ===== continue ===== // ৩. জোড় সংখ্যা skip করা: for (let i = 1; i <= 10; i++) { if (i % 2===0) continue; // জোড় হলে skip console.log(i); // → 1, 3, 5, 7, 9 } // ৪. ফাঁকা মান skip করে processing: const data=["করিম", "" , "রাহেলা" , null, "সজল" , undefined, "নিলু" ]; for (const item of data) { if (!item) continue; // ফাঁকা হলে skip console.log(item.toUpperCase()); } // → করিম, রাহেলা, সজল, নিলু (uppercase উদাহরণ) // ৫. ফিল্টার ছাড়া continue: const students=[ { name: "আরিফ" , passed: true }, { name: "বিথি" , passed: false }, { name: "চাঁদনী" , passed: true }, ]; for (const s of students) { if (!s.passed) continue; // ফেলরা skip console.log(`${s.name} পাস করেছে`); } // → আরিফ পাস করেছে // → চাঁদনী পাস করেছে

Label — Nested Loop Control Advanced

// Label দিয়ে Nested Loop বের হওয়া: // গঠন: labelName: for (...) { ... break labelName; } // ১. Nested loop থেকে সরাসরি বাইরের loop বন্ধ: outerLoop: for (let i = 0; i < 3; i++) { for (let j=0; j < 3; j++) { if (i===1 && j===1) { console.log(`i=${i}, j=${j} — বাইরে বের হচ্ছি`); break outerLoop; // বাইরের loop-ও বন্ধ } console.log(`i=${i}, j=${j}`); } } // → i=0, j=0 // → i=0, j=1 // → i=0, j=2 // → i=1, j=0 // → i=1, j=1 — বাইরে বের হচ্ছি (i=1,j=2 আর i=2 চলবে না) // ২. Label + continue — নির্দিষ্ট iteration skip: outer: for (let i=0; i < 3; i++) { for (let j=0; j < 3; j++) { if (j===1) continue outer; // বাইরের loop-এর পরের iteration-এ যাও console.log(`i=${i}, j=${j}`); } } // → i=0, j=0 // → i=1, j=0 // → i=2, j=0 (j=1 হলেই বাইরের loop-এ চলে যায়) // ৩. Matrix-এ নির্দিষ্ট মান খোঁজা: const grid=[ [1, 2, 3], [4, 5, 6], [7, 8, 9], ]; let foundRow=-1, foundCol=-1; search: for (let r=0; r < grid.length; r++) { for (let c=0; c < grid[r].length; c++) { if (grid[r][c]===5) { foundRow=r; foundCol=c; break search; // খুঁজে পেয়েছি, সব loop বন্ধ } } } console.log(`5 পাওয়া গেছে: row=${foundRow}, col=${foundCol}`); // → 5 পাওয়া গেছে: row=1, col=1

🔷 Iterators ও Iteration Protocol

Iteration Protocol হলো JavaScript-এর অভ্যন্তরীণ নিয়ম যা বলে কোনো Object iterate করা যাবে কিনা এবং কীভাবে। দুটো অংশ — Iterable Protocol এবং Iterator Protocol

Iterable ও Iterator Protocol Protocol

Protocol প্রয়োজনীয় Method Return করে ব্যবহার
Iterable [Symbol.iterator]() Iterator object for...of, Spread, Destructuring
Iterator next() { value, done } একের পর এক মান দেওয়া
// ===== Built-in Iterator দেখা ===== const arr = ["ক", "খ", "গ"]; const iterator = arr[Symbol.iterator](); // Iterator বের করা console.log(iterator.next()); // → { value: "ক", done: false } console.log(iterator.next()); // → { value: "খ", done: false } console.log(iterator.next()); // → { value: "গ", done: false } console.log(iterator.next()); // → { value: undefined, done: true } // String-এর Iterator: const str = "হ্যালো"; const strIt = str[Symbol.iterator](); console.log(strIt.next()); // → { value: "হ", done: false } // Map-এর Iterator: const map = new Map([["a", 1], ["b", 2]]); const mapIt = map[Symbol.iterator](); console.log(mapIt.next()); // → { value: ["a", 1], done: false } // ===== নিজের Iterable তৈরি ===== // Range Object — from থেকে to পর্যন্ত iterate করে: const range = { from: 1, to: 5, [Symbol.iterator]() { let current = this.from; const last = this.to; return { next() { if (current <= last) { return { value: current++, done: false }; } return { value: undefined, done: true }; }, }; }, }; // এখন for...of দিয়ে iterate করা যাবে: for (const num of range) { console.log(num); // → 1, 2, 3, 4, 5 } // Spread-ও কাজ করবে: console.log([...range]); // → [1, 2, 3, 4, 5]

Custom Iterator-এর Practical ব্যবহার Real-world

// LinkedList-এর মতো Iterable: class NumberRange { constructor(start, end, step = 1) { this.start = start; this.end = end; this.step = step; } [Symbol.iterator]() { let current = this.start; const { end, step } = this; return { next() { if (current <= end) { const value=current; current +=step; return { value, done: false }; } return { value: undefined, done: true }; }, }; } } // ব্যবহার: const evens=new NumberRange(2, 10, 2); // 2, 4, 6, 8, 10 for (const n of evens) { console.log(n); // → 2, 4, 6, 8, 10 } const range5=new NumberRange(1, 5); console.log([...range5]); // → [1, 2, 3, 4, 5] const [first, second]=new NumberRange(10, 50, 10); console.log(first, second); // → 10, 20

🔷 Generators — Lazy Iteration

Generator হলো বিশেষ ধরনের function যা মাঝপথে থামতে (yield) এবং আবার শুরু হতে (next()) পারে। এটি Iterator Protocol স্বয়ংক্রিয়ভাবে implement করে — তাই for...of দিয়ে সরাসরি iterate করা যায়।

Generator Function-এর গঠন Syntax

// গঠন: function* functionName() { yield value; } // ১. সাধারণ Generator: function* simpleGen() { console.log("প্রথম yield-এর আগে"); yield 1; console.log("দ্বিতীয় yield-এর আগে"); yield 2; console.log("তৃতীয় yield-এর আগে"); yield 3; console.log("শেষ — done: true"); } const gen = simpleGen(); // Generator Object তৈরি (এখনো চলেনি) console.log(gen.next()); // → প্রথম yield-এর আগে → { value: 1, done: false } console.log(gen.next()); // → দ্বিতীয় yield-এর আগে → { value: 2, done: false } console.log(gen.next()); // → তৃতীয় yield-এর আগে → { value: 3, done: false } console.log(gen.next()); // → শেষ — done: true → { value: undefined, done: true } // ২. for...of দিয়ে Generator iterate: function* fruitsGen() { yield "আম"; yield "কলা"; yield "লিচু"; } for (const fruit of fruitsGen()) { console.log(fruit); // → আম, কলা, লিচু } // Spread দিয়েও: console.log([...fruitsGen()]); // → ["আম", "কলা", "লিচু"]

Generator-এর বিশেষ ক্ষমতা Features

// ৩. Infinite Sequence — শেষ নেই এমন সিকোয়েন্স: function* naturals() { let n = 1; while (true) { // Infinite loop — কিন্তু প্রতিটি call-এ একটু একটু চলে yield n++; } } const gen = naturals(); console.log(gen.next().value); // → 1 console.log(gen.next().value); // → 2 console.log(gen.next().value); // → 3 // হাজার বার next() করা যাবে! // প্রথম ১০টি: function take(gen, count) { const result = []; for (const val of gen) { result.push(val); if (result.length >= count) break; } return result; } console.log(take(naturals(), 10)); // → [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] // ৪. next()-এ মান পাঠানো — দুমুখী যোগাযোগ: function* calculator() { const x = yield "প্রথম সংখ্যা দাও:"; const y = yield "দ্বিতীয় সংখ্যা দাও:"; return x + y; } const calc = calculator(); console.log(calc.next()); // → { value: "প্রথম সংখ্যা দাও:", done: false } console.log(calc.next(10)); // → { value: "দ্বিতীয় সংখ্যা দাও:", done: false } (x=10) console.log(calc.next(20)); // → { value: 30, done: true } (y=20, return 10+20) // ৫. yield* — অন্য Generator বা Iterable delegate করা: function* firstThree() { yield 1; yield 2; yield 3; } function* combined() { yield* firstThree(); // firstThree-এর সব মান yield* [4, 5, 6]; // Array-ও yield 7; } console.log([...combined()]); // → [1, 2, 3, 4, 5, 6, 7]

Generator-এর Practical ব্যবহার Real-world

// ৬. Unique ID Generator: function* idGenerator(prefix = "ID") { let id = 1; while (true) { yield `${prefix}-${String(id++).padStart(4, "0")}`; } } const userId = idGenerator("USR"); console.log(userId.next().value); // → USR-0001 console.log(userId.next().value); // → USR-0002 console.log(userId.next().value); // → USR-0003 // ৭. Pagination Generator — বড় ডেটা ছোট ছোট ভাগে: function* paginate(data, pageSize) { for (let i = 0; i < data.length; i +=pageSize) { yield data.slice(i, i + pageSize); } } const allStudents=["করিম", "রাহেলা" , "সজল" , "নিলু" , "আরিফ" , "বিথি" , "চাঁদনী" ]; const pages=paginate(allStudents, 3); console.log(pages.next().value); // → ["করিম", "রাহেলা" , "সজল" ] console.log(pages.next().value); // → ["নিলু", "আরিফ" , "বিথি" ] console.log(pages.next().value); // → ["চাঁদনী"] // ৮. Fibonacci Generator: function* fibonacci() { let [a, b]=[0, 1]; while (true) { yield a; [a, b]=[b, a + b]; } } const fib=fibonacci(); console.log(take(fib, 8)); // → [0, 1, 1, 2, 3, 5, 8, 13]
Generator কখন ব্যবহার করবে?
→ Infinite sequence তৈরিতে (ID, Fibonacci)।
→ বড় ডেটা Lazy-ভাবে process করতে (পুরো ডেটা মেমোরিতে না রেখে)।
→ Custom Iterable সহজে তৈরিতে।
→ Async flow control-এ (async/await-এর আগে Redux-Saga এটা ব্যবহার করত)।

🔷 দ্রুত রেফারেন্স — JavaScript Loops and Iterations

কোন Loop কখন ব্যবহার করবে? Decision Guide

পরিস্থিতি সেরা পছন্দ কারণ
কতবার চলবে আগে থেকে জানা for Counter স্পষ্ট, initialization ও update এক জায়গায়
শর্ত পূরণ না হওয়া পর্যন্ত while কতবার চলবে অনিশ্চিত
কমপক্ষে একবার চালাতেই হবে do...while Exit-controlled, Menu ও Validation-এ উপকারী
Object-এর সব Key দরকার for...in Enumerable property iterate করে
Array, Map, Set-এর মান দরকার for...of যেকোনো Iterable-এ কাজ করে, পরিষ্কার syntax
Array-এ রূপান্তর বা ফিল্টার map / filter / reduce Functional style, নতুন Array ফেরত দেয়
Infinite বা Lazy sequence Generator (function*) প্রয়োজন মতো মান তৈরি করে
Async ডেটা একটির পর একটি for await...of Async Iterable ও Stream handle করে

সব Loop-এর গঠন এক নজরে Syntax Summary

Loop গঠন শর্ত চেক
for for (init; cond; update) { } আগে (Entry)
while while (cond) { } আগে (Entry)
do...while do { } while (cond); পরে (Exit)
for...in for (const key in obj) { } স্বয়ংক্রিয়
for...of for (const val of iterable) { } স্বয়ংক্রিয়
for await...of for await (const val of asyncIt) { } স্বয়ংক্রিয়

সাধারণ ভুল ও সমাধান Common Mistakes

ভুল সমস্যা সমাধান
for (var i...) var Function-scoped — async-এ bug let ব্যবহার করো
for...in Array-এ String index, prototype property for...of বা forEach
Loop-এ update ভুলে যাওয়া Infinite Loop — ব্রাউজার হ্যাং counter সঠিকভাবে update করো
forEach-এ break forEach-এ break কাজ করে না for...of ব্যবহার করো
Loop-এ Mutation চলমান Array পরিবর্তন করলে skip হয় copy-তে iterate করো [...arr]
for...of Plain Object-এ Object iterable নয় — TypeError Object.entries() দিয়ে wrap করো

Array-এর Iteration Methods এক নজরে Array Methods

Method কাজ Return break সম্ভব?
forEach() প্রতিটিতে কাজ করে undefined ❌ না
map() প্রতিটি রূপান্তর করে নতুন Array ❌ না
filter() শর্তপূরণকারী রাখে নতুন Array ❌ না
reduce() একটি মানে সংকুচিত যেকোনো মান ❌ না
find() প্রথম মিল খোঁজে মান বা undefined ✅ স্বয়ংক্রিয়
some() একটি মিললেই true boolean ✅ স্বয়ংক্রিয়
every() সব মিললে true boolean ✅ স্বয়ংক্রিয়
for...of যেকোনো Iterable ✅ break সম্ভব

🧠 নিজেকে যাচাই করো

1. for...of কোথায় ব্যবহার করি?

2. forEach() ও map() পার্থক্য?

3. break statement কী করে?

✏️ Task — এখন তুমি করো

skills array-টা for, for...of, forEach, map — চারটা দিয়ে iterate করো।

ধাপ 7🏗️ Real Project — Interactive Portfolio

Portfolio-এ skills ও projects loop দিয়ে render করো।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio-এর সব skills ও projects DOM-এ loop দিয়ে render করো।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

🔀 JavaScript Control Flow — সম্পূর্ণ নোট

এই সেকশনে JavaScript-এর সব ধরনের Control Flow — Conditional Statements, Exception Handling, Throw Statement, Try/Catch/Finally, এবং Error Objects — বাংলায় উদাহরণসহ বিস্তারিত আলোচনা করা হয়েছে।


🔷 Control Flow কী ও কেন প্রয়োজন?

Control Flow হলো প্রোগ্রামের কোন অংশ কখন ও কীভাবে চলবে তা নির্ধারণ করার পদ্ধতি। সাধারণত কোড উপর থেকে নিচে ক্রমানুসারে চলে — Control Flow Structure এই ক্রম পরিবর্তন করে।

সহজ উদাহরণ — পরীক্ষায় ৩৩ বা তার বেশি পেলে "পাস", না হলে "ফেল" — এই সিদ্ধান্তটুকু নেওয়ার জন্যই Control Flow দরকার। আর কোনো Error হলে প্রোগ্রাম বন্ধ না হয়ে সামলে নেওয়ার জন্য দরকার Exception Handling।

ধরন Keyword / Operator কাজ ES Version
Conditional if...else শর্ত অনুযায়ী ভিন্ন পথ নেওয়া ES1
Multi-branch switch...case একটি মানের বিরুদ্ধে একাধিক case তুলনা ES1
Ternary ? : এক লাইনে if...else ES1
Logical && || ! Logical শর্ত জুড়ে দেওয়া ও Short-circuit ES1
Nullish Coalescing ?? null/undefined হলে fallback মান ES2020
Optional Chaining ?. null/undefined হলে Error না দিয়ে undefined ES2020
Exception Handling try...catch...finally Error ধরে সামলানো, প্রোগ্রাম চালু রাখা ES3
Throw Statement throw নিজে Error তৈরি করে ছোড়া ES3

🔷 Conditional Statements — শর্তভিত্তিক সিদ্ধান্ত

Conditional Statement হলো শর্তের ফলাফলের উপর ভিত্তি করে ভিন্ন ভিন্ন কোড চালানোর পদ্ধতি। JavaScript-এ তিন ধরনের Conditional Statement আছে।

if...else — সবচেয়ে মৌলিক Conditional if...else

// ১. শুধু if: const score = 75; if (score >= 33) { console.log("পাস ✅"); // → পাস ✅ } // ২. if...else: const age = 16; if (age >= 18) { console.log("ভোট দিতে পারবে"); } else { console.log("ভোট দিতে পারবে না"); // → ভোট দিতে পারবে না } // ৩. if...else if...else — একাধিক শর্ত: const marks = 82; let grade; if (marks >= 80) { grade = "A+"; } else if (marks >= 70) { grade = "A"; } else if (marks >= 60) { grade = "A-"; } else if (marks >= 50) { grade = "B"; } else if (marks >= 33) { grade = "C"; } else { grade = "F"; } console.log(`গ্রেড: ${grade}`); // → গ্রেড: A+ // ৪. Guard Clause — Nested if এড়ানোর সেরা পদ্ধতি: function checkAdmission(age, marks, hasDocuments) { // ব্যর্থ শর্ত আগেই return করো: if (age < 5 || age> 16) return "বয়স সীমার বাইরে"; if (marks < 50) return "নম্বর কম — ভর্তি সম্ভব নয়" ; if (!hasDocuments) return "কাগজপত্র জমা দিন" ; return "ভর্তি অনুমোদিত ✅" ; // সব শর্ত পার হলে এখানে } console.log(checkAdmission(10, 65, true)); // → ভর্তি অনুমোদিত ✅ console.log(checkAdmission(20, 65, true)); // → বয়স সীমার বাইরে console.log(checkAdmission(10, 40, true)); // → নম্বর কম

switch...case — একাধিক নির্দিষ্ট মান তুলনা switch

// সাধারণ switch: const day = 3; switch (day) { case 1: console.log("শনিবার"); break; case 2: console.log("রবিবার"); break; case 3: console.log("সোমবার"); break; // → সোমবার case 4: console.log("মঙ্গলবার"); break; case 5: console.log("বুধবার"); break; default: console.log("অজানা দিন"); } // ইচ্ছাকৃত Fall-through — একাধিক case একই কাজ: const month = 4; let season; switch (month) { case 12: case 1: case 2: season = "শীতকাল"; break; case 3: case 4: case 5: season = "বসন্তকাল"; break; // → বসন্তকাল case 6: case 7: case 8: case 9: season = "বর্ষাকাল"; break; case 10: case 11: season = "হেমন্তকাল"; break; default: season = "অজানা"; } console.log(season); // Object Lookup — switch-এর আধুনিক বিকল্প: function getDayName(num) { const days = { 1: "শনিবার", 2: "রবিবার", 3: "সোমবার", 4: "মঙ্গলবার", 5: "বুধবার", 6: "বৃহস্পতিবার", 7: "শুক্রবার", }; return days[num] ?? "অজানা"; } console.log(getDayName(3)); // → সোমবার

Ternary Operator (? :) — এক লাইনের সিদ্ধান্ত Ternary

// গঠন: condition ? valueIfTrue : valueIfFalse // ১. সাধারণ ব্যবহার: const userAge = 20; const status = userAge >= 18 ? "প্রাপ্তবয়স্ক" : "অপ্রাপ্তবয়স্ক"; console.log(status); // → প্রাপ্তবয়স্ক // ২. Template Literal-এ: const s = 45; console.log(`ফলাফল: ${s >= 33 ? "পাস ✅" : "ফেল ❌"}`); // → পাস ✅ // ৩. Function return-এ: const getDiscount = (isMember) => isMember ? 20 : 5; console.log(getDiscount(true)); // → 20 console.log(getDiscount(false)); // → 5 // ৪. Default মান দেওয়া: function greet(name) { name = name ? name : "অতিথি"; return `আস-সালামু আলাইকুম, ${name}!`; } console.log(greet("করিম")); // → আস-সালামু আলাইকুম, করিম! console.log(greet("")); // → আস-সালামু আলাইকুম, অতিথি! // ❌ Nested Ternary — এড়িয়ে চলো: const m = 75; const g = m >= 80 ? "A+" : m >= 70 ? "A" : m >= 60 ? "A-" : "B"; // পড়তে কঠিন! // ✅ সমাধান — if...else বা function: function getGrade(m) { if (m >= 80) return "A+"; if (m >= 70) return "A"; if (m >= 60) return "A-"; return "B"; } console.log(getGrade(75)); // → A

Logical Operators ও Short-circuit Logical

// && (AND) — প্রথম falsy মান ফেরত, নইলে শেষ মান: console.log(true && "হ্যালো"); // → "হ্যালো" console.log(false && "হ্যালো"); // → false (থামল) console.log(null && doSomething()); // → null (doSomething call হয়নি!) // || (OR) — প্রথম truthy মান ফেরত: console.log(false || "ডিফল্ট"); // → "ডিফল্ট" console.log("মান" || "ডিফল্ট"); // → "মান" // ?? (Nullish Coalescing) — শুধু null/undefined হলে fallback: console.log(0 || 100); // → 100 ⚠️ (0 falsy) console.log(0 ?? 100); // → 0 ✅ (0 null/undefined নয়) console.log(null ?? 100); // → 100 ✅ // ?. (Optional Chaining) — null/undefined-এ Error নয়: const user = null; console.log(user?.name); // → undefined (Error নেই ✅) console.log(user?.address?.city); // → undefined const obj = { greet: () => "হ্যালো" }; console.log(obj.greet?.()); // → হ্যালো console.log(obj.bye?.()); // → undefined (Error নেই ✅)
Conditional Statement বেছে নেওয়ার নিয়ম:
→ সাধারণ শর্ত → if...else
→ ৩+ নির্দিষ্ট মান → switch বা Object Lookup
→ এক লাইনে সহজ দুটো বিকল্প → Ternary ? :
→ null/undefined fallback → ?? (0 বা "" valid হলে || নয়!)

🔷 Exception Handling — পরিচিতি ও ধারণা

Exception হলো প্রোগ্রাম চলাকালে ঘটা অপ্রত্যাশিত Error বা অস্বাভাবিক পরিস্থিতি। Exception Handling হলো এই Error-কে ধরে সামলানোর পদ্ধতি — যাতে পুরো প্রোগ্রাম crash না করে সঠিকভাবে কাজ চালিয়ে যেতে পারে।

Exception কেন হয়? — কারণসমূহ কারণ

কারণের ধরন উদাহরণ কে দায়ী?
Programming Error null.property, undefined() প্রোগ্রামার
User Input Error Text field-এ সংখ্যার জায়গায় অক্ষর ব্যবহারকারী
Network / API Error Server বন্ধ, Timeout, 404 Not Found পরিবেশ
Resource Error File নেই, Database সংযোগ ব্যর্থ পরিবেশ
Logic Error শূন্য দিয়ে ভাগ, Stack Overflow প্রোগ্রামার

Error না ধরলে কী হয়? সমস্যা

// Error না ধরলে — প্রোগ্রাম crash করে: const data = null; console.log(data.name); // ❌ TypeError: Cannot read properties of null console.log("এই লাইন কখনো চলবে না"); // → কখনো পৌঁছাবে না! // Exception Handling দিয়ে — প্রোগ্রাম চলতে থাকে: try { console.log(data.name); // Error হবে } catch (error) { console.log("Error সামলানো হয়েছে:", error.message); } console.log("প্রোগ্রাম চলছে..."); // → চলবে ✅

Exception Handling-এর চারটি উপাদান উপাদান

উপাদান কাজ বাধ্যতামূলক?
try Error হতে পারে এমন কোড রাখা হয় ✅ হ্যাঁ
catch Error ধরে সামলানো হয় finally থাকলে না-ও হতে পারে
finally Error হোক বা না হোক সবসময় চলে ❌ ঐচ্ছিক
throw নিজে Error তৈরি করে ছোড়া ❌ ঐচ্ছিক

🔷 Throw Statement — নিজে Error তৈরি ও ছোড়া

throw statement দিয়ে নিজে Exception তৈরি করে ছোড়া যায়। throw চালু হলে বর্তমান function সাথে সাথে বন্ধ হয় এবং নিকটতম catch block-এ যায়।

throw-এর গঠন ও যা throw করা যায় Syntax

// গঠন: throw expression; // যেকোনো মান throw করা যায়: // throw "Error Message"; // String ⚠️ — এড়িয়ে চলো // throw 404; // Number ⚠️ — এড়িয়ে চলো // throw { msg: "Error" }; // Object ⚠️ — এড়িয়ে চলো // throw new Error("message"); // ✅ সেরা পদ্ধতি // ❌ String throw — stack trace নেই: try { throw "কিছু একটা ভুল হয়েছে"; } catch (e) { console.log(e); // → কিছু একটা ভুল হয়েছে console.log(e.stack); // → undefined (stack trace নেই!) } // ✅ Error Object throw — সব তথ্য পাওয়া যায়: try { throw new Error("কিছু একটা ভুল হয়েছে"); } catch (e) { console.log(e.message); // → কিছু একটা ভুল হয়েছে console.log(e.name); // → Error console.log(e.stack); // → Error: কিছু একটা... at :2:9 }

throw কীভাবে কাজ করে — Flow Flow

// throw করলে বাকি কোড চলে না: function riskyFunction() { console.log("১. কাজ শুরু"); throw new Error("মাঝপথে সমস্যা!"); console.log("২. এই লাইন কখনো চলবে না"); // → চলবে না } try { riskyFunction(); console.log("৩. এও চলবে না"); // → চলবে না } catch (error) { console.log("৪. Error ধরা পড়েছে:", error.message); } console.log("৫. প্রোগ্রাম চলছে"); // → চলবে ✅ // আউটপুট: // → ১. কাজ শুরু // → ৪. Error ধরা পড়েছে: মাঝপথে সমস্যা! // → ৫. প্রোগ্রাম চলছে

throw-এর Practical ব্যবহার Practical

// ১. Input Validation: function divide(a, b) { if (typeof a !== "number" || typeof b !== "number") { throw new TypeError("দুটো argument-ই সংখ্যা হতে হবে"); } if (b === 0) { throw new RangeError("শূন্য দিয়ে ভাগ করা যাবে না"); } return a / b; } try { console.log(divide(10, 2)); // → 5 console.log(divide(10, 0)); // → RangeError } catch (error) { console.log(`${error.name}: ${error.message}`); // → RangeError: শূন্য দিয়ে ভাগ করা যাবে না } // ২. User তৈরিতে Validation: function createUser(name, age) { if (typeof name !== "string" || name.trim() === "") { throw new TypeError("নাম অবশ্যই খালি নয় এমন String হতে হবে"); } if (typeof age !== "number" || age < 0 || age> 150) { throw new RangeError("বয়স ০ থেকে ১৫০-এর মধ্যে হতে হবে"); } return { name: name.trim(), age }; } try { const u1 = createUser("রাহেলা", 22); console.log(u1); // → { name: "রাহেলা", age: 22 } const u2 = createUser("", 22); // TypeError throw হবে } catch (error) { console.log(`${error.name}: ${error.message}`); // → TypeError: নাম অবশ্যই খালি নয় এমন String হতে হবে } // ৩. API Status চেক: async function fetchData(url) { const response = await fetch(url); if (!response.ok) { throw new Error(`HTTP Error: ${response.status} — ${response.statusText}`); } return await response.json(); } // ৪. throw আবার ছোড়া (Re-throw): function processJSON(text) { try { return JSON.parse(text); } catch (error) { if (error instanceof SyntaxError) { throw new Error(`JSON ভুল format-এ আছে: ${error.message}`); // আরও তথ্য যোগ করে নতুন Error throw } throw error; // অন্য Error সামলাব না — আবার ছুড়ে দাও } }

সঠিক Error Type বেছে throw করা Error Types

throw করো কখন? উদাহরণ
new Error(msg) সাধারণ, অশ্রেণীবদ্ধ Error Logic ব্যর্থ হলে
new TypeError(msg) ভুল type পাঠানো হলে String-এর জায়গায় Number এলে
new RangeError(msg) মান গ্রহণযোগ্য সীমার বাইরে বয়স ঋণাত্মক হলে
new ReferenceError(msg) বিরল — সাধারণত JS নিজে throw করে অঘোষিত variable
new SyntaxError(msg) Input format ভুল হলে ভুল JSON, ভুল Date format
Custom Error Class Domain-specific Error ValidationError, NetworkError

🔷 try...catch — Error ধরা ও সামলানো

try...catch হলো Exception Handling-এর মূল কাঠামো। try block-এ Error হলে বাকি কোড না চালিয়ে সরাসরি catch block-এ চলে যায় এবং Error Object পাওয়া যায়।

try...catch-এর গঠন ও প্রবাহ Syntax

// গঠন: // try { // // সম্ভাব্য Error-প্রবণ কোড // } catch (errorParameter) { // // Error সামলানো // } // ১. সাধারণ try...catch: try { const result = JSON.parse("{ invalid json }"); // Error হবে console.log(result); // → চলবে না } catch (error) { console.log("Error ধরা পড়েছে!"); // → চলবে ✅ console.log(error.message); // → Unexpected token... } console.log("প্রোগ্রাম চলছে..."); // → চলবে ✅ // ২. Error হলে vs না হলে প্রবাহ: function safeParse(text) { try { const data = JSON.parse(text); // সম্ভাব্য Error console.log("Parse সফল!"); // Error না হলে চলবে return data; } catch (error) { console.log("Parse ব্যর্থ:", error.message); // Error হলে চলবে return null; // default মান ফেরত } } console.log(safeParse('{"name":"করিম"}')); // → Parse সফল! → { name: "করিম" } console.log(safeParse("bad json")); // → Parse ব্যর্থ: ... → null // ৩. Error type অনুযায়ী ভিন্ন সামলানো: function handleError(action) { try { action(); } catch (error) { if (error instanceof TypeError) { console.log("Type সমস্যা:", error.message); } else if (error instanceof RangeError) { console.log("Range সমস্যা:", error.message); } else if (error instanceof SyntaxError) { console.log("Syntax সমস্যা:", error.message); } else { console.log("অজানা Error:", error.message); throw error; // অপরিচিত Error আবার throw } } } handleError(() => null.name); // → Type সমস্যা: Cannot read... handleError(() => new Array(-1)); // → Range সমস্যা: Invalid array length handleError(() => JSON.parse("{bad}")); // → Syntax সমস্যা: ...

Optional Catch Binding — catch-এ parameter ছাড়া ES2019

// ES2019 — error parameter ছাড়া catch: try { JSON.parse("bad json"); } catch { // error variable দরকার নেই console.log("JSON parse করতে সমস্যা হয়েছে"); } // কখন ব্যবহার করবে: function isValidJSON(text) { try { JSON.parse(text); return true; } catch { return false; // error details দরকার নেই } } console.log(isValidJSON('{"name":"করিম"}')); // → true console.log(isValidJSON("bad json")); // → false

Async/Await-এ try...catch Async

// Async Function-এ try...catch: async function loadUserData(userId) { try { const response = await fetch(`/api/users/${userId}`); if (!response.ok) { throw new Error(`Server Error: ${response.status}`); } const user = await response.json(); console.log("ব্যবহারকারী পাওয়া গেছে:", user.name); return user; } catch (error) { if (error instanceof TypeError) { // Network error (fetch fail) console.log("নেটওয়ার্ক সমস্যা:", error.message); } else { console.log("Error:", error.message); } return null; } } // Promise chain-এ .catch(): fetch("/api/data") .then(res => { if (!res.ok) throw new Error(`HTTP ${res.status}`); return res.json(); }) .then(data => console.log("ডেটা:", data)) .catch(error => console.log("Promise Error:", error.message)); // Nested try...catch: async function complexOperation() { try { try { const data = await fetch("/api/primary"); return await data.json(); } catch { // Primary API fail — backup try করো: console.log("Primary API fail, backup চেষ্টা..."); const backup = await fetch("/api/backup"); return await backup.json(); } } catch (error) { console.log("সব API fail:", error.message); return null; } }
⚠️ try...catch সীমাবদ্ধতা: try...catch শুধু Synchronous Error ধরে। Asynchronous callback-এর Error ধরতে পারে না। Async Error-এর জন্য async/await + try...catch অথবা .catch() ব্যবহার করো।

🔷 finally — সবসময় চলে

finally block সবসময় চলে — try block সফল হলেও, catch block চললেও, এমনকি return করা হলেও। Cleanup কাজ রাখার এটাই সঠিক জায়গা।

finally-এর গঠন ও ব্যবহার Syntax

// গঠন: // try { ... } catch (e) { ... } finally { ... } // অথবা: try { ... } finally { ... } (catch ছাড়াও হয়) // ১. তিনটি পথেই finally চলে: function example(n) { try { if (n === 1) return "try থেকে return"; if (n === 2) throw new Error("ইচ্ছাকৃত Error"); return "সফল"; } catch (e) { return "catch থেকে return"; } finally { console.log("finally সবসময় চলে!"); // সব ক্ষেত্রেই চলে } } example(1); // → finally সবসময় চলে! → "try থেকে return" example(2); // → finally সবসময় চলে! → "catch থেকে return" example(3); // → finally সবসময় চলে! → "সফল" // ২. Cleanup — File, Connection, Loader: function readFile(filename) { let fileHandle = null; try { fileHandle = openFile(filename); // simulation return processFile(fileHandle); } catch (error) { console.log("File পড়তে সমস্যা:", error.message); return null; } finally { // Error হোক বা না হোক — file অবশ্যই বন্ধ করো: if (fileHandle) { fileHandle.close?.(); // file বন্ধ console.log("File বন্ধ করা হয়েছে ✅"); } } } // ৩. Loading State — UI-তে: async function fetchWithLoader(url) { showLoader(); // loading শুরু try { const response = await fetch(url); return await response.json(); } catch (error) { showError(error.message); return null; } finally { hideLoader(); // সবসময় loader বন্ধ করো // Error হলেও, সফল হলেও loader অবশ্যই বন্ধ হবে } }

finally-তে return — সাবধানতা সাবধান

// finally-তে return করলে try/catch-এর return override হয়: function dangerousFinally() { try { throw new Error("Error!"); } catch (e) { return "catch-এর মান"; // এটা override হবে! } finally { return "finally-র মান"; // ⚠️ এটাই শেষ পর্যন্ত return হয় } } console.log(dangerousFinally()); // → "finally-র মান" ⚠️ // catch-এর Error নীরবে হারিয়ে যায়! // ✅ সঠিক — finally-তে return এড়িয়ে চলো: function safeFinally() { try { throw new Error("Error!"); } catch (e) { return "catch-এর মান"; } finally { console.log("cleanup হচ্ছে"); // শুধু cleanup, return নেই } } console.log(safeFinally()); // → cleanup হচ্ছে → "catch-এর মান" ✅

try...finally — catch ছাড়া Pattern

// Cleanup নিশ্চিত করতে catch ছাড়াও finally ব্যবহার হয়: // Error ধরবে না, কিন্তু cleanup সবসময় হবে। function withLock(resource, operation) { acquireLock(resource); // Lock নেওয়া try { return operation(); // কাজ করো // Error হলে এখানে থামবে } finally { releaseLock(resource); // সবসময় Lock ছাড়ো // Error হলে Error উপরে যাবে, কিন্তু Lock আগে ছাড়া হবে } } // Database Transaction: async function withTransaction(db, operation) { await db.beginTransaction(); try { const result = await operation(db); await db.commit(); // সফল হলে commit return result; } catch (error) { await db.rollback(); // Error হলে rollback throw error; // Error আবার throw — caller জানুক } finally { await db.closeConnection(); // সবসময় connection বন্ধ } }

🔷 Error Objects — বিস্তারিত ব্যবহার

Error Object হলো Error সম্পর্কিত সব তথ্য ধারণকারী বিশেষ Object। catch block-এ যে parameter আসে সেটাই Error Object। এর property ব্যবহার করে debugging ও user-friendly বার্তা দেওয়া যায়।

Error Object-এর সব Property Properties

Property ধরন কী দেয়? ES
name String Error-এর নাম: "TypeError", "RangeError" ইত্যাদি ES1
message String Error-এর মানুষপাঠ্য বর্ণনা ES1
stack String কোন file, কোন line-এ Error হয়েছে (Stack trace) Non-standard কিন্তু সব Browser সাপোর্ট করে
cause যেকোনো Error-এর মূল কারণ (Error chaining-এ) ES2022
// Error Object-এর সব property দেখা: try { null.property; // TypeError } catch (error) { console.log(error.name); // → TypeError console.log(error.message); // → Cannot read properties of null (reading 'property') console.log(error.stack); // → TypeError: Cannot read properties of null (reading 'property') // at :2:7 // at ... // instanceof চেক: console.log(error instanceof TypeError); // → true console.log(error instanceof Error); // → true (সব Error, Error-এর subclass) } // Error তৈরির সময় তথ্য দেওয়া: const err = new Error("কিছু ভুল হয়েছে"); console.log(err.name); // → Error console.log(err.message); // → কিছু ভুল হয়েছে // ES2022 — cause দিয়ে Error chaining: async function fetchUser(id) { try { const res = await fetch(`/api/users/${id}`); return res.json(); } catch (networkError) { throw new Error( `ব্যবহারকারী ${id} লোড করা যায়নি`, { cause: networkError } // মূল Error সংরক্ষণ ); } } try { await fetchUser(123); } catch (error) { console.log(error.message); // → ব্যবহারকারী 123 লোড করা যায়নি console.log(error.cause); // → মূল NetworkError (debugging-এ সাহায্য করে) }

Built-in Error Types — বিস্তারিত Types

Error Type কখন হয়? উদাহরণ Code সমাধান
Error সাধারণ base Error throw new Error("msg") নির্দিষ্ট subtype নির্বাচন করো
TypeError ভুল type-এ operation null.property, undefined() type চেক করো আগে
ReferenceError অঘোষিত variable console.log(notDeclared) variable ঘোষণা করো
SyntaxError ভুল JavaScript syntax JSON.parse("{bad}") input validate করো
RangeError মান সীমার বাইরে new Array(-1), (1.2).toFixed(200) bound চেক করো
URIError URI function-এ ভুল decodeURIComponent("%") encode করার আগে validate করো
EvalError eval() সংক্রান্ত আধুনিক JS-এ বিরল eval() ব্যবহার করো না
// প্রতিটি Built-in Error দেখা: // TypeError: try { null.name; } catch (e) { console.log(e instanceof TypeError, e.name); } // → true "TypeError" // ReferenceError: try { console.log(notExistVar); } catch (e) { console.log(e instanceof ReferenceError, e.name); } // → true "ReferenceError" // SyntaxError: try { JSON.parse("{bad json}"); } catch (e) { console.log(e instanceof SyntaxError, e.name); } // → true "SyntaxError" // RangeError: try { new Array(-1); } catch (e) { console.log(e instanceof RangeError, e.name); } // → true "RangeError" // URIError: try { decodeURIComponent("%"); } catch (e) { console.log(e instanceof URIError, e.name); } // → true "URIError"

🔷 Custom Error Class — নিজের Error তৈরি

Custom Error Class তৈরি করলে নিজের domain-specific Error-কে আলাদাভাবে চেনা যায়, অতিরিক্ত তথ্য রাখা যায় এবং catch block-এ ভিন্নভাবে সামলানো যায়।

Custom Error Class তৈরি Class

// মূল কাঠামো — Error extend করো: class AppError extends Error { constructor(message) { super(message); // Error-এর message সেট this.name = "AppError"; // name সেট — না করলে "Error" থাকে } } // ব্যবহার: try { throw new AppError("অ্যাপে সমস্যা হয়েছে"); } catch (error) { console.log(error.name); // → AppError console.log(error.message); // → অ্যাপে সমস্যা হয়েছে console.log(error instanceof AppError); // → true console.log(error instanceof Error); // → true (subclass)

অতিরিক্ত Property সহ Custom Error Advanced

// Validation Error — কোন field-এ সমস্যা: class ValidationError extends Error { constructor(message, field, value) { super(message); this.name = "ValidationError"; this.field = field; // কোন field-এ সমস্যা this.value = value; // কী মান দেওয়া হয়েছিল } } // Network Error — HTTP status code সহ: class NetworkError extends Error { constructor(message, statusCode, url) { super(message); this.name = "NetworkError"; this.statusCode = statusCode; this.url = url; } // Custom method: isClientError() { return this.statusCode >= 400 && this.statusCode < 500; } isServerError() { return this.statusCode>= 500; } } // Database Error: class DatabaseError extends Error { constructor(message, query) { super(message); this.name = "DatabaseError"; this.query = query; // কোন query-তে সমস্যা this.timestamp = new Date(); // কখন হয়েছে } } // ব্যবহার — Form Validation: function validateForm(data) { if (!data.name || data.name.trim() === "") { throw new ValidationError( "নাম খালি রাখা যাবে না", "name", data.name ); } if (!data.email || !data.email.includes("@")) { throw new ValidationError( "সঠিক Email দিন", "email", data.email ); } if (!data.age || data.age < 18) { throw new ValidationError( "বয়স কমপক্ষে ১৮ হতে হবে" , "age" , data.age ); } return true; } try { validateForm({ name: "" , email: "test@mail.com" , age: 20 }); } catch (error) { if (error instanceof ValidationError) { console.log(`Field: ${error.field}`); // → Field: name console.log(`Error: ${error.message}`); // → Error: নাম খালি রাখা যাবে না console.log(`Value: "${error.value}" `); // → Value: "" } }

Error Hierarchy — শ্রেণীবিন্যাস Hierarchy

// Error Hierarchy তৈরি — বড় প্রজেক্টে উপকারী: class AppError extends Error { constructor(message, code) { super(message); this.name = "AppError"; this.code = code; // নিজস্ব error code } } class ClientError extends AppError { constructor(message, code = "CLIENT_ERROR") { super(message, code); this.name = "ClientError"; } } class ServerError extends AppError { constructor(message, code = "SERVER_ERROR") { super(message, code); this.name = "ServerError"; } } class AuthError extends ClientError { constructor(message) { super(message, "AUTH_ERROR"); this.name = "AuthError"; } } class NotFoundError extends ClientError { constructor(resource) { super(`${resource} পাওয়া যায়নি`, "NOT_FOUND"); this.name = "NotFoundError"; this.resource = resource; } } // চেইনের যেকোনো স্তরে ধরা যায়: try { throw new NotFoundError("ব্যবহারকারী"); } catch (error) { console.log(error instanceof NotFoundError); // → true console.log(error instanceof ClientError); // → true console.log(error instanceof AppError); // → true console.log(error instanceof Error); // → true console.log(error.message); // → ব্যবহারকারী পাওয়া যায়নি console.log(error.code); // → NOT_FOUND console.log(error.resource); // → ব্যবহারকারী }

Error Type দিয়ে সিদ্ধান্ত নেওয়া Real-world

// বিভিন্ন Error-এ ভিন্ন আচরণ: async function handleAPICall(endpoint) { try { const response = await fetch(endpoint); if (response.status === 401) { throw new AuthError("লগইন করুন"); } if (response.status === 404) { throw new NotFoundError("রিসোর্স"); } if (response.status >= 500) { throw new ServerError(`Server Error: ${response.status}`); } return await response.json(); } catch (error) { if (error instanceof AuthError) { redirectToLogin(); // লগইন পেজে নিয়ে যাও } else if (error instanceof NotFoundError) { show404Page(); // 404 পেজ দেখাও } else if (error instanceof ServerError) { showRetryButton(); // Retry option দেখাও } else if (error instanceof TypeError) { console.log("নেটওয়ার্ক সমস্যা"); // Offline হলে } else { logError(error); // অজানা Error — log করো showGenericError(); } } }

🔷 Error Handling-এর সেরা অভ্যাস

Error Handling-এর সম্পূর্ণ Pattern Pattern

// ✅ সম্পূর্ণ Error Handling Pattern: class UserService { async getUser(id) { // ১. Input Validation — আগেই চেক করো: if (!id || typeof id !== "number") { throw new ValidationError("ID অবশ্যই সংখ্যা হতে হবে", "id", id); } try { // ২. সম্ভাব্য ব্যর্থ অপারেশন try-এ: const response = await fetch(`/api/users/${id}`); // ৩. HTTP Error চেক: if (!response.ok) { throw new NetworkError( `ব্যবহারকারী লোড ব্যর্থ`, response.status, `/api/users/${id}` ); } return await response.json(); } catch (error) { // ৪. নির্দিষ্ট Error সামলাও, বাকি re-throw: if (error instanceof NetworkError && error.statusCode === 404) { return null; // না পেলে null — acceptable } throw error; // অন্য Error caller-কে জানাও } finally { // ৫. Cleanup সবসময়: logRequest(`getUser(${id})`); } } } // ৬. সর্বোচ্চ স্তরে সব Error ধরো: window.addEventListener("unhandledrejection", (event) => { console.error("Unhandled Promise rejection:", event.reason); // User-কে জানাও }); process.on("uncaughtException", (error) => { console.error("Uncaught Exception:", error); process.exit(1); // Node.js-এ graceful shutdown });

করো ✅ ও করো না ❌ Best Practices

করো না ❌ করো ✅ কারণ
throw "Error text" throw new Error("text") Error Object-এ stack trace পাওয়া যায়
catch (e) {} (চুপ থাকা) catch (e) { log(e); } Silent failure সবচেয়ে বিপজ্জনক
সব Error এক catch-এ instanceof দিয়ে ভাগ করো নির্দিষ্ট Error-এ নির্দিষ্ট সামলানো
finally-তে return finally-তে শুধু cleanup return করলে Error নীরবে হারায়
শুধু error.message দেখানো error.stack log করো Stack trace ছাড়া debugging কঠিন
Async callback-এ try...catch async/await + try...catch Callback-এর Error ধরা যায় না
User-কে stack trace দেখানো User-বান্ধব বার্তা দেখাও Security ও UX উভয় কারণে

Error Logging — সঠিকভাবে রেকর্ড করা Logging

// Error তথ্য সম্পূর্ণভাবে log করা: function logError(error, context = {}) { const errorInfo = { name: error.name, message: error.message, stack: error.stack, cause: error.cause, timestamp: new Date().toISOString(), ...context, // অতিরিক্ত তথ্য (userId, action ইত্যাদি) }; console.error("[ERROR]", JSON.stringify(errorInfo, null, 2)); // Production-এ Error tracking service-এ পাঠাও: // Sentry.captureException(error, { extra: context }); } // ব্যবহার: try { await riskyOperation(); } catch (error) { logError(error, { userId: currentUser.id, action: "riskyOperation", input: sanitizedInput, // password ছাড়া! }); // User-কে friendly message: showToast("কিছু একটা ভুল হয়েছে। আবার চেষ্টা করুন।"); }

🔷 দ্রুত রেফারেন্স — JavaScript Control Flow

কোন Control Flow কখন ব্যবহার করবে? Decision Guide

পরিস্থিতি সেরা পছন্দ কারণ
দুটো পথের মধ্যে সিদ্ধান্ত if...else স্পষ্ট, সব ধরনের শর্ত সামলায়
একটি মানের বিরুদ্ধে ৩+ নির্দিষ্ট case switch / Object Lookup পরিষ্কার syntax, Object Lookup আরও আধুনিক
এক লাইনে সহজ দুটো বিকল্প Ternary (? :) Template Literal ও JSX-এ উপকারী
null বা undefined হলে fallback ?? 0, false, "" রক্ষা করে — || করে না
Nested property নিরাপদে access ?. Error না দিয়ে undefined ফেরত দেয়
Error সামলানো try...catch...finally Error ধরে প্রোগ্রাম চালু রাখে
নিজে Error তৈরি throw new Error() Validation ও Business logic enforce করতে
Domain-specific Error Custom Error Class instanceof দিয়ে নির্দিষ্টভাবে চেনা যায়

try...catch...finally এক নজরে Summary

Block কখন চলে? Error হলে? বাধ্যতামূলক?
try সবসময় Error-এ বন্ধ হয়ে catch-এ যায় ✅ হ্যাঁ
catch শুধু Error হলে Error Object পাওয়া যায় finally থাকলে না-ও হয়
finally সবসময় — Error, return যাই হোক Error হলেও চলে, তারপর Error যায় ❌ ঐচ্ছিক

সাধারণ ভুল ও সমাধান Common Mistakes

ভুল কোড সমস্যা সঠিক কোড
throw "Error" String-এ stack trace নেই throw new Error("Error")
catch (e) {} Error নীরবে হারায় — সবচেয়ে বিপজ্জনক catch (e) { console.error(e); }
finally-তে return try/catch-এর return ও Error override finally-তে শুধু cleanup রাখো
count || 10 (count=0) 0 falsy — 10 পাবে অথচ 0 valid count ?? 10
user.address.city address null হলে TypeError user?.address?.city
switch-এ break বাদ Fall-through — পরের case-ও চলে প্রতিটি case-এ break দাও

🧠 নিজেকে যাচাই করো

1. if-else if-else কখন?

2. switch vs if-else কোনটা better?

3. ternary operator কী?

✏️ Task — এখন তুমি করো

Grade calculator বানাও। Score দিলে A, B, C, D, F grade বলবে।

ধাপ 8🏗️ Real Project — Interactive Portfolio

Portfolio-এ skill level checker বানাও।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio-এ form validation যোগ করো। সব field check করো।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

🧮 JavaScript Expressions and Operators — সম্পূর্ণ নোট

এই সেকশনে JavaScript-এর সব ধরনের Expressions ও Operators — Assignment, Arithmetic, Comparison, Logical, Bitwise, String, Ternary, typeof, instanceof, Spread, Comma এবং আরও অনেক কিছু — বাংলায় উদাহরণসহ বিস্তারিত আলোচনা করা হয়েছে।


🔷 Expression ও Operator কী?

Expression হলো JavaScript-এর যেকোনো বৈধ কোড যা একটি মান উৎপাদন করে। Operator হলো সেই চিহ্ন যা এক বা একাধিক মানের (Operand) উপর কাজ করে নতুন মান তৈরি করে।

সহজ উদাহরণ — 5 + 3-তে + হলো Operator, 53 হলো Operand, এবং পুরো 5 + 3 হলো একটি Expression যার মান 8

Operator-এর ধরন চিহ্ন / Keyword কাজ ES Version
Assignment = += -= ইত্যাদি Variable-এ মান রাখা ES1
Arithmetic + - * / % ** গণিতের হিসাব ES1 / ES2016
Comparison == === != > < দুটো মান তুলনা করে Boolean দেয় ES1
Logical && || ! ?? Logical শর্ত ও Short-circuit ES1 / ES2020
Bitwise & | ^ ~ << >> Bit-স্তরে binary অপারেশন ES1
String + += Template Literal String জোড়া লাগানো ES1 / ES6
Unary typeof void delete ! + - একটি operand-এ কাজ করে ES1
Relational instanceof in Object-এর ধরন ও property চেক ES1
Ternary ? : এক লাইনে if...else ES1
Spread / Rest ... Iterable ছড়ানো বা গোছানো ES6
Comma , একাধিক expression evaluate করে শেষেরটা ফেরত ES1

Expression বনাম Statement পার্থক্য

// ===== Expressions — মান তৈরি করে ===== 5 + 3 // → 8 "হ্যালো" // → "হ্যালো" true // → true x = 10 // → 10 (assignment নিজেও expression!) greet() // → function-এর return মান [1, 2, 3] // → Array { name: "করিম" } // → Object // ===== Statements — কাজ করে, মান তৈরি করে না ===== if (x > 0) { } // if statement for (let i = 0; i < 5; i++) { } // for statement function greet() { } // function declaration // Expression Statement=Expression-কে Statement হিসেবে ব্যবহার: console.log("হ্যালো"); // function call expression → statement x++; // increment expression → statement // IIFE — Immediately Invoked Function Expression: const result=(function() { return 42; })(); // function expression তৈরি করে তাৎক্ষণিক call console.log(result); // → 42

Operator-এর Arity — কতটি Operand নেয়? Arity

Arity Operand সংখ্যা উদাহরণ
Unary ১টি -x, !true, typeof x, x++
Binary ২টি 5 + 3, x === y, a && b
Ternary ৩টি cond ? a : b

🔷 Assignment Operators — মান রাখার Operator

Assignment Operator বাম দিকের variable-এ ডান দিকের মান রাখে। মূল = ছাড়াও Compound Assignment Operator আছে যা একসাথে calculation ও assignment করে।

Simple ও Compound Assignment Operators

Operator উদাহরণ সমতুল্য ফলাফল (x=10)
= x = 5 x = 5
+= x += 3 x = x + 3 x = 13
-= x -= 3 x = x - 3 x = 7
*= x *= 3 x = x * 3 x = 30
/= x /= 2 x = x / 2 x = 5
%= x %= 3 x = x % 3 x = 1
**= x **= 2 x = x ** 2 x = 100
// Simple Assignment: let score = 0; score = 85; console.log(score); // → 85 // Compound Assignment — প্রতিটির উদাহরণ: let x = 10; x += 5; console.log(x); // → 15 x -= 3; console.log(x); // → 12 x *= 2; console.log(x); // → 24 x /= 4; console.log(x); // → 6 x %= 4; console.log(x); // → 2 x **= 3; console.log(x); // → 8 // Practical — শপিং কার্টে মোট যোগ: let total = 0; const items = [150, 250, 80, 320]; for (const price of items) { total += price; // প্রতিটি দাম যোগ হচ্ছে } console.log(`মোট: ৳${total}`); // → মোট: ৳800 // Chained Assignment: let a, b, c; a = b = c = 42; // ডান থেকে বামে console.log(a, b, c); // → 42 42 42 // Destructuring Assignment: let p = 1, q = 2; [p, q] = [q, p]; // swap! console.log(p, q); // → 2 1 const { name, age } = { name: "করিম", age: 25, city: "ঢাকা" }; console.log(name, age); // → করিম 25 // Logical Assignment (ES2021): let settings = { theme: null, fontSize: 0, sound: false }; settings.theme ??= "light"; // null → assign settings.fontSize ??= 14; // 0 — null/undefined নয়, পরিবর্তন নেই! settings.sound ||= true; // false → assign console.log(settings); // → { theme: "light", fontSize: 0, sound: true }

🔷 Arithmetic Operators — গণিতের Operator

Arithmetic Operators সংখ্যার উপর গণিতের হিসাব করে। JavaScript-এ + operator বিশেষ — String থাকলে সংযোজনের (concatenation) কাজ করে।

মূল Arithmetic Operators Operators

Operator নাম উদাহরণ ফলাফল
+ যোগ / String Concat 5 + 3 / "হ্যা" + "লো" 8 / "হ্যালো"
- বিয়োগ 10 - 4 6
* গুণ 4 * 5 20
/ ভাগ 15 / 4 3.75
% ভাগশেষ (Modulo) 10 % 3 1
** ঘাত (Exponentiation) 2 ** 10 1024
+x Unary Plus (Number-এ convert) +"42" 42
-x Unary Minus (চিহ্ন বদলায়) -5 -5
// মূল Arithmetic: console.log(10 + 3); // → 13 console.log(10 - 3); // → 7 console.log(10 * 3); // → 30 console.log(10 / 3); // → 3.3333... console.log(10 % 3); // → 1 console.log(2 ** 10); // → 1024 (2^10) // বিশেষ ক্ষেত্র: console.log(0 / 0); // → NaN console.log(5 / 0); // → Infinity console.log(-5 / 0); // → -Infinity // % (Modulo) ব্যবহার: // জোড়/বিজোড় চেক: console.log(4 % 2 === 0); // → true (জোড়) console.log(7 % 2 === 0); // → false (বিজোড়) // বৃত্তাকার Array index: const colors = ["লাল", "সবুজ", "নীল"]; for (let i = 0; i < 9; i++) { console.log(colors[i % colors.length]); // → লাল, সবুজ, নীল, লাল, সবুজ... } // ** (Exponentiation): console.log(2 ** 8); // → 256 console.log(9 ** 0.5); // → 3 (√9) console.log((-2) ** 3); // → -8 (unary minus-এর আগে () লাগবে) // Unary + — String → Number: console.log(+"42"); // → 42 console.log(+"3.14"); // → 3.14 console.log(+true); // → 1 console.log(+false); // → 0 console.log(+null); // → 0 console.log(+undefined); // → NaN console.log(+"হ্যালো"); // → NaN // + String concatenation বিপদ: console.log(1 + "2" ); // → "12" ⚠️ (String!) console.log("3" - 1); // → 2 ✅ (- String convert করে) console.log("6" / "2" ); // → 3 ✅ (/ ও convert করে) console.log("5" * "4" ); // → 20 ✅ (* ও convert করে)

Increment ও Decrement Operators ++ / --

// Prefix Increment (++x) — আগে বাড়ায়: let a = 5; console.log(++a); // → 6 (আগে বাড়িয়ে তারপর দেখায়) console.log(a); // → 6 // Postfix Increment (x++) — পরে বাড়ায়: let b = 5; console.log(b++); // → 5 (আগে দেখায়, তারপর বাড়ায়) console.log(b); // → 6 // Prefix Decrement (--x): let c = 5; console.log(--c); // → 4 // Postfix Decrement (x--): let d = 5; console.log(d--); // → 5 console.log(d); // → 4 // ব্যবহারিক পার্থক্য: let i = 0; const arr = []; while (i < 3) { arr.push(i++); // push করার সময় i-র পুরানো মান push, তারপর i বাড়ে } console.log(arr); // → [0, 1, 2] // Math সম্পর্কিত দরকারি: console.log(Math.floor(7 / 2)); // → 3 (পূর্ণসংখ্যায় ভাগ) console.log(Math.abs(-15)); // → 15 (পরম মান) console.log(Math.round(4.6)); // → 5 (নিকটতম পূর্ণসংখ্যা) console.log(Math.ceil(4.1)); // → 5 (উপরে) console.log(Math.max(3, 7, 1)); // → 7 console.log(Math.min(3, 7, 1)); // → 1

Operator Precedence — অগ্রাধিকার Precedence

// গণিতের মতোই — * এবং / আগে, + এবং - পরে: console.log(2 + 3 * 4); // → 14 (3*4=12, তারপর 2+12) console.log((2 + 3) * 4); // → 20 (brackets আগে) console.log(10 - 2 + 3); // → 11 (বাম থেকে ডানে) console.log(2 ** 3 ** 2); // → 512 (** ডান থেকে বামে: 3**2=9, 2**9=512) console.log((2 ** 3) ** 2); // → 64 (2**3=8, 8**2=64) // Mixed: console.log(5 + 3 > 2 * 3); // → true (8 > 6) console.log(typeof 42 === "number"); // → true console.log(!false && 1 + 1 === 2); // → true
মনে রাখার নিয়ম: Precedence মুখস্থ না করে সন্দেহ হলে Parentheses () ব্যবহার করো। কোড পরিষ্কার থাকে ও ভুলের সম্ভাবনা কমে।

🔷 Comparison Operators — তুলনার Operator

Comparison Operator দুটো মান তুলনা করে সবসময় true অথবা false ফেরত দেয়।

Operator নাম উদাহরণ ফলাফল
== Abstract Equality (Type Coercion) "5" == 5 true ⚠️
=== Strict Equality (কোনো Coercion নেই) "5" === 5 false
!= Abstract Inequality "5" != 5 false ⚠️
!== Strict Inequality "5" !== 5 true
> বড় 10 > 5 true
< ছোট 3 < 7 true
>= বড় বা সমান 5 >= 5 true
<= ছোট বা সমান 4 <= 5 true
// === সবসময় ব্যবহার করো: console.log(5 === 5); // → true console.log("5" === 5); // → false (type আলাদা) console.log(null === null); // → true console.log(NaN === NaN); // → false ⚠️ (NaN বিশেষ!) // NaN চেক করতে: console.log(Number.isNaN(NaN)); // → true ✅ // Relational — String-এ সাবধান: console.log("10" > "9"); // → false ⚠️ (String তুলনা: "1" < "9" ) console.log(10> "9"); // → true ✅ (Number তুলনা) console.log("10" > 9); // → true ✅ ("10" → 10) // Practical — বয়স যাচাই: function checkAge(age) { if (typeof age !== "number" || age < 0 || age> 150) { return "অবৈধ বয়স"; } if (age >= 18) return "প্রাপ্তবয়স্ক"; if (age >= 13) return "কিশোর"; return "শিশু"; } console.log(checkAge(25)); // → প্রাপ্তবয়স্ক console.log(checkAge(15)); // → কিশোর console.log(checkAge(8)); // → শিশু // Object তুলনা — Reference: console.log({} === {}); // → false (আলাদা reference) console.log([] === []); // → false (আলাদা reference) const arr = [1, 2]; const arr2 = arr; console.log(arr === arr2); // → true (একই reference)

🔷 Logical Operators — যুক্তির Operator

Logical Operators শুধু Boolean নয় — যেকোনো মানে কাজ করে এবং Short-circuit করে। অর্থাৎ ফলাফল নিশ্চিত হলে বাকি অংশ evaluate করে না।

Logical Operators বিস্তারিত Operators

Operator নাম Short-circuit ফেরত দেয়
A && B AND A falsy হলে A, B evaluate হয় না প্রথম falsy, নইলে B
A || B OR A truthy হলে A, B evaluate হয় না প্রথম truthy, নইলে B
!A NOT Boolean বিপরীত
A ?? B Nullish Coalescing A null/undefined হলে B A (null/undefined নয়), নইলে B
// ===== && (AND) ===== console.log(true && "হ্যালো"); // → "হ্যালো" (truthy && truthy → শেষ) console.log(false && "হ্যালো"); // → false (falsy → থামল) console.log(0 && "হ্যালো"); // → 0 (0 falsy) console.log("বাংলা" && 42); // → 42 (দুটোই truthy → শেষ) // && Practical — নিরাপদ property access: const user = { name: "রাহেলা", isAdmin: true }; user.isAdmin && console.log("Admin Panel"); // → Admin Panel null && console.log("না চলবে না"); // → null (চলবে না) // ===== || (OR) ===== console.log(false || "ডিফল্ট"); // → "ডিফল্ট" console.log("মান" || "ডিফল্ট"); // → "মান" console.log(0 || 42); // → 42 (0 falsy) // || Practical — Default মান: function greet(name) { const n = name || "অতিথি"; // name falsy হলে "অতিথি" return `স্বাগতম, ${n}!`; } console.log(greet("করিম")); // → স্বাগতম, করিম! console.log(greet("")); // → স্বাগতম, অতিথি! // ===== ! (NOT) ===== console.log(!true); // → false console.log(!false); // → true console.log(!0); // → true (0 falsy) console.log(!""); // → true (খালি string falsy) console.log(!null); // → true console.log(!!"মান"); // → true (!! দিয়ে Boolean-এ convert) console.log(!!0); // → false // ===== ?? (Nullish Coalescing) ===== console.log(null ?? "ডিফল্ট"); // → "ডিফল্ট" console.log(undefined ?? "ডিফল্ট"); // → "ডিফল্ট" console.log(0 ?? "ডিফল্ট"); // → 0 ✅ (0 null/undefined নয়!) console.log("" ?? "ডিফল্ট"); // → "" ✅ console.log(false ?? "ডিফল্ট"); // → false ✅ // Chained Logical: const config = {}; const port = config.port || process?.env?.PORT || 3000; const dbName = config.db?.name ?? "default_db"; console.log(port); // → 3000 console.log(dbName); // → "default_db"

🔷 Bitwise Operators — Binary Bit-স্তরের Operator

Bitwise Operator সংখ্যাকে 32-bit binary-তে রূপান্তর করে প্রতিটি bit-এর উপর সরাসরি কাজ করে। সাধারণ web dev-এ কম লাগলেও Permission System, Color Processing, Performance Optimization-এ কাজে আসে।

Bitwise Operators Operators

Operator নাম উদাহরণ Binary ব্যাখ্যা ফলাফল
& AND 5 & 3 0101 & 0011 = 0001 1
| OR 5 | 3 0101 | 0011 = 0111 7
^ XOR 5 ^ 3 0101 ^ 0011 = 0110 6
~ NOT (Bitwise) ~5 ~00000101 = 11111010 -6
<< Left Shift 5 << 1 0101 → 1010 10
>> Right Shift (Sign-preserving) 20 >> 2 10100 → 00101 5
>>> Unsigned Right Shift -1 >>> 0 সব bit shift 4294967295
// ===== Bitwise AND (&) ===== // উভয় bit 1 হলে 1: // 5 = 0101 // 3 = 0011 // 5&3 = 0001 = 1 console.log(5 & 3); // → 1 // জোড়/বিজোড় চেক (% এর চেয়ে দ্রুত): console.log(4 & 1); // → 0 (জোড়) console.log(7 & 1); // → 1 (বিজোড়) // ===== Bitwise OR (|) ===== // যেকোনো bit 1 হলে 1: console.log(5 | 3); // → 7 (0111) // ===== Bitwise XOR (^) ===== // bit আলাদা হলে 1: console.log(5 ^ 3); // → 6 (0110) // XOR দিয়ে swap (temporary variable ছাড়া): let x = 10, y = 20; x ^= y; y ^= x; x ^= y; console.log(x, y); // → 20 10 // ===== Left/Right Shift ===== // Left Shift = 2 দিয়ে গুণ: console.log(1 << 0); // → 1 (2^0) console.log(1 << 1); // → 2 (2^1) console.log(1 << 2); // → 4 (2^2) console.log(1 << 10); // → 1024 (2^10) // Right Shift=2 দিয়ে ভাগ: console.log(20>> 1); // → 10 (20/2) console.log(20 >> 2); // → 5 (20/4) // ===== Practical: Permission System ===== // Flag-based permission — Bitwise অনেক দক্ষ: const READ = 1; // 001 const WRITE = 2; // 010 const EXECUTE = 4; // 100 // Permission যোগ করা (|): const userPerm = READ | WRITE; // 011 = 3 console.log(userPerm); // → 3 // Permission চেক করা (&): console.log((userPerm & READ) !== 0); // → true (read আছে) console.log((userPerm & WRITE) !== 0); // → true (write আছে) console.log((userPerm & EXECUTE) !== 0); // → false (execute নেই) // Permission সরানো (XOR বা AND NOT): const noWrite = userPerm & ~WRITE; // WRITE bit সরাও console.log((noWrite & WRITE) !== 0); // → false ✅ // ===== ~ (Bitwise NOT) দিয়ে indexOf চেক ===== // পুরানো trick: ~(-1) = 0 (falsy), অন্য যেকোনো index truthy const fruits = ["আম", "কলা", "লিচু"]; if (~fruits.indexOf("কলা")) { console.log("কলা আছে!"); // → কলা আছে! } // আধুনিক পদ্ধতি: fruits.includes("কলা")
Bitwise কখন ব্যবহার করবে: Permission/Flag System, Color manipulation (RGB), Game development-এ performance-critical কোড, Binary data processing। সাধারণ কাজে এড়িয়ে চলো — কোড পড়া কঠিন হয়।

🔷 String Operators ও Template Literals

JavaScript-এ String-এর জন্য ++= Operator আছে। তবে ES6-এর Template Literal অনেক বেশি শক্তিশালী ও পড়তে সহজ।

String Concatenation ও Template Literal String

// পুরানো পদ্ধতি — + দিয়ে: const name = "করিম"; const age = 25; const msg1 = "আমার নাম " + name + " এবং বয়স " + age + " বছর।"; console.log(msg1); // → আমার নাম করিম এবং বয়স 25 বছর। // += দিয়ে append: let text = "হ্যালো"; text += " বাংলাদেশ"; text += "!"; console.log(text); // → হ্যালো বাংলাদেশ! // ✅ আধুনিক পদ্ধতি — Template Literal (Backtick ``): const msg2 = `আমার নাম ${name} এবং বয়স ${age} বছর।`; console.log(msg2); // → আমার নাম করিম এবং বয়স 25 বছর। // Expression এম্বেড করা যায়: const a = 5, b = 3; console.log(`${a} + ${b} = ${a + b}`); // → 5 + 3 = 8 console.log(`${a > b ? "বড়" : "ছোট"}`); // → বড় console.log(`${name.toUpperCase()}`); // → করিম (function call) console.log(`π ≈ ${Math.PI.toFixed(4)}`); // → π ≈ 3.1416 // Multi-line String: const poem = ` আমার সোনার বাংলা, আমি তোমায় ভালোবাসি। চিরদিন তোমার আকাশ, তোমার বাতাস, আমার প্রাণে বাজায় বাঁশি। `.trim(); console.log(poem); // Nested Template Literal: const items = ["আম", "কলা", "লিচু"]; const list = `ফলের তালিকা: ${items.map((item, i) => ` ${i + 1}. ${item}`).join("\n")}`; console.log(list); // → ফলের তালিকা: // → 1. আম // → 2. কলা // → 3. লিচু

Tagged Template Literal — উন্নত ব্যবহার ES6

// Tagged Template Literal গঠন: // tagFunction`string ${expr} string` // HTML Escape করার জন্য: function safeHTML(strings, ...values) { const escaped = values.map(v => String(v) .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) ); return strings.reduce((result, str, i) => result + str + (escaped[i] ?? ""), ""); } const userInput = ' <script> alert("XSS")</script>'; const html = safeHTML`

ব্যবহারকারী বলেছেন: ${userInput}

`; console.log(html); // →

ব্যবহারকারী বলেছেন: <script>alert("XSS")</script>

// CSS-in-JS (styled-components style): function css(strings, ...values) { return strings.reduce((result, str, i) => result + str + (values[i] ?? ""), ""); } const color = "blue"; const style = css`color: ${color}; font-size: 16px;`; console.log(style); // → color: blue; font-size: 16px;

🔷 Unary Operators — typeof, void, delete

Unary Operator একটিমাত্র Operand নিয়ে কাজ করে। typeof, void, delete হলো keyword-based Unary Operator।

typeof — type জানার Operator typeof

// typeof সব মানে: console.log(typeof 42); // → "number" console.log(typeof 3.14); // → "number" console.log(typeof NaN); // → "number" ⚠️ (NaN তবুও "number"!) console.log(typeof "হ্যালো"); // → "string" console.log(typeof true); // → "boolean" console.log(typeof false); // → "boolean" console.log(typeof undefined); // → "undefined" console.log(typeof null); // → "object" ⚠️ (বিখ্যাত JavaScript bug!) console.log(typeof {}); // → "object" console.log(typeof []); // → "object" ⚠️ (Array-ও "object") console.log(typeof function(){}); // → "function" console.log(typeof Symbol()); // → "symbol" console.log(typeof 42n); // → "bigint" // typeof-এর সুবিধা — undeclared variable-এও Error নেই: console.log(typeof undeclaredVar); // → "undefined" (Error নেই!) // console.log(undeclaredVar); // → ReferenceError ❌ // Practical — type চেক: function processInput(input) { if (typeof input === "string") { return input.toUpperCase(); } else if (typeof input === "number") { return input * 2; } else if (typeof input === "boolean") { return !input; } return null; } console.log(processInput("হ্যালো")); // → হ্যালো (uppercase) console.log(processInput(21)); // → 42 console.log(processInput(true)); // → false // Array চেক করতে typeof নয় — Array.isArray(): console.log(Array.isArray([])); // → true ✅ console.log(typeof [] === "array"); // → false (typeof দেয় "object") // null চেক করতে typeof নয় — === ব্যবহার করো: const val = null; console.log(val === null); // → true ✅ console.log(typeof val === "null"); // → false ❌

void — undefined ফেরত দেওয়া void

// void যেকোনো expression-কে undefined করে: console.log(void 0); // → undefined console.log(void "হ্যালো"); // → undefined console.log(void (1 + 2)); // → undefined (expression চলে কিন্তু মান ফেলে) // void 0 — undefined-এর নিরাপদ alias (পুরানো browser-এ undefined overwrite হত): const undef = void 0; console.log(undef); // → undefined // IIFE-তে void: void (function() { console.log("চলছে কিন্তু মান ফেরত দেয় না"); })(); // Arrow function-এ side effect নিশ্চিত করতে: const onClick = () => void someFunction(); // return মান দরকার নেই

delete — Object Property মুছে ফেলা delete

// Object property মুছে ফেলা: const student = { name: "রাহেলা", age: 20, score: 92 }; console.log(student); // → { name: "রাহেলা", age: 20, score: 92 } delete student.age; console.log(student); // → { name: "রাহেলা", score: 92 } console.log(student.age); // → undefined (property নেই) // delete-এর return মান: console.log(delete student.score); // → true (সফল) console.log(delete student.xyz); // → true (নেই তবুও true) // ⚠️ Array-এ delete — hole তৈরি হয়: const arr = [1, 2, 3, 4, 5]; delete arr[2]; // index 2 মুছে console.log(arr); // → [1, 2, empty, 4, 5] ⚠️ console.log(arr.length); // → 5 (length পরিবর্তন হয়নি!) console.log(arr[2]); // → undefined // ✅ Array থেকে সরাতে splice ব্যবহার করো: const arr2 = [1, 2, 3, 4, 5]; arr2.splice(2, 1); // index 2 থেকে 1টি সরাও console.log(arr2); // → [1, 2, 4, 5] ✅ // let/const-এ delete কাজ করে না: let x = 10; console.log(delete x); // → false (কাজ করেনি) console.log(x); // → 10 (অপরিবর্তিত)

🔷 Relational Operators — instanceofin

Relational Operator দুটো মানের মধ্যে বিশেষ সম্পর্ক পরীক্ষা করে। instanceof Object-এর type চেক করে, আর in Object-এর property চেক করে।

instanceof — Object-এর type চেক instanceof

// instanceof — Prototype chain চেক করে: console.log([] instanceof Array); // → true console.log([] instanceof Object); // → true (Array, Object-এর subtype) console.log({} instanceof Object); // → true console.log("str" instanceof String); // → false (Primitive, Object নয়) console.log(42 instanceof Number); // → false (Primitive) // Class-এ instanceof: class Animal { constructor(name) { this.name = name; } } class Dog extends Animal { bark() { return "ঘেউ!"; } } const rex = new Dog("রেক্স"); console.log(rex instanceof Dog); // → true console.log(rex instanceof Animal); // → true (subclass) console.log(rex instanceof Object); // → true (সব Object) // Error-এ instanceof: try { null.property; } catch (e) { console.log(e instanceof TypeError); // → true console.log(e instanceof Error); // → true console.log(e instanceof RangeError); // → false } // Array চেক — instanceof ভালো কিন্তু Array.isArray() আরও ভালো: const arr = [1, 2, 3]; console.log(arr instanceof Array); // → true ✅ console.log(Array.isArray(arr)); // → true ✅ (iframe-এও কাজ করে)

in — Object-এ Property আছে কিনা in

// in — property আছে কিনা: const person = { name: "করিম", age: 25, city: "ঢাকা" }; console.log("name" in person); // → true console.log("age" in person); // → true console.log("email" in person); // → false // undefined মান থাকলেও true: const obj = { score: undefined }; console.log("score" in obj); // → true ✅ console.log(obj.score === undefined); // → true (কিন্তু আছে!) // hasOwnProperty vs in: console.log(obj.hasOwnProperty("score")); // → true (নিজের) console.log("toString" in obj); // → true (Prototype থেকে) console.log(obj.hasOwnProperty("toString")); // → false (Prototype-এর, নিজের নয়) // Array-এ index চেক: const fruits = ["আম", "কলা", "লিচু"]; console.log(0 in fruits); // → true (index 0 আছে) console.log(3 in fruits); // → false (index 3 নেই) console.log("length" in fruits); // → true (Array-এর property) // for...in-এর সাথে পার্থক্য: const car = { brand: "Toyota", model: "Corolla" }; for (const key in car) { if (Object.hasOwn(car, key)) { // in + hasOwnProperty একসাথে console.log(`${key}: ${car[key]}`); } } // Practical — Optional feature চেক: if ("geolocation" in navigator) { console.log("GPS আছে"); } if ("serviceWorker" in navigator) { console.log("Service Worker সাপোর্ট আছে"); }

🔷 Spread (...) ও Rest Operator

... (তিনটি dot) context অনুযায়ী দুটো ভিন্ন কাজ করে। Spread হলো ছড়ানো — Iterable-কে আলাদা উপাদানে বিভক্ত করে। Rest হলো গোছানো — একাধিক উপাদানকে একটি Array-এ রাখে।

Spread বনাম Rest পার্থক্য পার্থক্য

বিষয় Spread ... Rest ...
কাজ ছড়িয়ে দেয় (expand) গোছায় (collect)
কোথায়? Expression-এ (call, literal) Parameter ও Destructuring-এ
উদাহরণ Math.max(...arr) function f(...args)
// ===== Spread Operator ===== // ১. Array copy ও merge: const arr1 = [1, 2, 3]; const arr2 = [4, 5, 6]; const copy = [...arr1]; // → [1, 2, 3] (নতুন Array) const merged = [...arr1, ...arr2]; // → [1, 2, 3, 4, 5, 6] const withNew = [...arr1, 10, ...arr2]; // → [1, 2, 3, 10, 4, 5, 6] // ২. Function call-এ: const nums = [3, 1, 4, 1, 5, 9, 2]; console.log(Math.max(...nums)); // → 9 console.log(Math.min(...nums)); // → 1 function sum(a, b, c) { return a + b + c; } console.log(sum(...[10, 20, 30])); // → 60 // ৩. String → Array: const chars = [..."বাংলাদেশ"]; console.log(chars); // → ["ব", "া", "ং", "ল", "া", "দ", "ে", "শ"] // ৪. Object copy ও merge: const defaults = { theme: "light", lang: "bn", size: 14 }; const custom = { lang: "en", size: 16 }; const settings = { ...defaults, ...custom }; // custom override করে console.log(settings); // → { theme: "light", lang: "en", size: 16 } // Property যোগ করা: const user = { name: "করিম", age: 25 }; const updatedUser = { ...user, email: "karim@example.com", age: 26 }; console.log(updatedUser); // → { name: "করিম", age: 26, email: "karim@example.com" } // ===== Rest Operator ===== // ৫. Function-এ Rest parameter: function sumAll(...numbers) { // সব argument এক Array-এ return numbers.reduce((a, b) => a + b, 0); } console.log(sumAll(1, 2, 3)); // → 6 console.log(sumAll(1, 2, 3, 4, 5)); // → 15 // First ও Rest আলাদা করা: function logFirst(first, ...rest) { console.log("প্রথম:", first); console.log("বাকি:", rest); } logFirst("ক", "খ", "গ", "ঘ"); // → প্রথম: ক // → বাকি: ["খ", "গ", "ঘ"] // ৬. Destructuring-এ Rest: const [head, ...tail] = [1, 2, 3, 4, 5]; console.log(head); // → 1 console.log(tail); // → [2, 3, 4, 5] const { name, ...others } = { name: "রাহেলা", age: 22, city: "ঢাকা" }; console.log(name); // → রাহেলা console.log(others); // → { age: 22, city: "ঢাকা" }

🔷 অন্যান্য গুরুত্বপূর্ণ Operators

Ternary Operator (? :) Ternary

// গঠন: condition ? valueIfTrue : valueIfFalse const age = 20; const status = age >= 18 ? "প্রাপ্তবয়স্ক" : "অপ্রাপ্তবয়স্ক"; console.log(status); // → প্রাপ্তবয়স্ক // Template Literal-এ: const score = 75; console.log(`ফলাফল: ${score >= 33 ? "পাস ✅" : "ফেল ❌"}`); // Short-circuit-এর বিকল্প: const user = null; const name = user ? user.name : "অজানা"; // user truthy হলে name, নইলে "অজানা" console.log(name); // → অজানা

Optional Chaining (?.) ও Nullish Coalescing (??) ES2020

// ?. — null/undefined-এ Error না দিয়ে undefined: const company = { address: { city: "ঢাকা" } }; console.log(company?.address?.city); // → ঢাকা console.log(company?.ceo?.name); // → undefined (Error নেই ✅) console.log(company?.getInfo?.()); // → undefined (method নেই) console.log(company?.items?.[0]); // → undefined (array access) // ?? — শুধু null/undefined হলে fallback: const port = null ?? 3000; // → 3000 const host = "" ?? "localhost"; // → "" (খালি string nullish নয়!) const timeout = 0 ?? 5000; // → 0 (0 nullish নয়!) // ?. ও ?? মিলিয়ে: const response = null; const city = response?.data?.address?.city ?? "অজানা শহর"; console.log(city); // → অজানা শহর

Comma Operator (,) Comma

// Comma Operator — সব evaluate করে শেষেরটা ফেরত দেয়: const x = (1, 2, 3, 4, 5); console.log(x); // → 5 (শুধু শেষেরটা) // for loop-এ একাধিক variable: for (let i = 0, j = 10; i < j; i++, j--) { console.log(i, j); // → 0 10, 1 9, 2 8, 3 7, 4 6 } // Destructuring-এ skip করতে: const [, second, , fourth]=[1, 2, 3, 4]; console.log(second, fourth); // → 2 4

Operator Precedence সম্পূর্ণ তালিকা Precedence

Precedence Operator Associativity
19 (সর্বোচ্চ) () Grouping
18 . [] () ?. Member Access, Call বাম → ডান
17 new (argument সহ)
15 ! ~ +x -x typeof void delete await ডান → বাম
14 ** ডান → বাম
13 * / % বাম → ডান
12 + - বাম → ডান
11 << >> >>> বাম → ডান
10 < <= > >= in instanceof বাম → ডান
9 == != === !== বাম → ডান
8-6 & ^ | বাম → ডান
5 && বাম → ডান
4 || ?? বাম → ডান
3 ? : Ternary ডান → বাম
2 = += -= ইত্যাদি Assignment ডান → বাম
1 (সর্বনিম্ন) , Comma বাম → ডান

🔷 BigInt Operators — অনেক বড় সংখ্যার Operator

BigInt হলো ES2020-এর নতুন numeric type যা Number.MAX_SAFE_INTEGER (253-1)-এর চেয়ে বড় যেকোনো পূর্ণসংখ্যা সঠিকভাবে রাখতে পারে। সংখ্যার শেষে n লিখলে BigInt হয়।

BigInt তৈরি ও মূল বৈশিষ্ট্য Basics

// BigInt তৈরি: const big1 = 9007199254740991n; // n suffix const big2 = BigInt("9007199254740991"); // BigInt() constructor const big3 = BigInt(42); // Number → BigInt console.log(typeof big1); // → "bigint" console.log(big1 === big2); // → true // Number-এর সীমা সমস্যা: const maxSafe = Number.MAX_SAFE_INTEGER; // 9007199254740991 console.log(maxSafe + 1); // → 9007199254740992 console.log(maxSafe + 2); // → 9007199254740992 ⚠️ (ভুল! +1 ও +2 একই!) // BigInt-এ সীমা নেই: const bigNum = 9007199254740991n; console.log(bigNum + 1n); // → 9007199254740992n ✅ console.log(bigNum + 2n); // → 9007199254740993n ✅ // বিশাল সংখ্যা সঠিকভাবে: console.log(2n ** 100n); // → 1267650600228229401496703205376n ✅ (Number-এ অসম্ভব)

BigInt-এ Arithmetic Operators Arithmetic

Operator উদাহরণ ফলাফল বিশেষত্ব
+ 10n + 3n 13n স্বাভাবিক
- 10n - 3n 7n স্বাভাবিক
* 10n * 3n 30n স্বাভাবিক
/ 10n / 3n 3n ⚠️ সবসময় পূর্ণসংখ্যা (দশমিক নেই)
% 10n % 3n 1n স্বাভাবিক
** 2n ** 10n 1024n স্বাভাবিক
-x -42n -42n চিহ্ন বদলায়
++ / -- let x = 1n; x++ 2n স্বাভাবিক
+x (Unary Plus) +42n TypeError ❌ BigInt-এ Unary + কাজ করে না
>>> 1n >>> 0n TypeError ❌ Unsigned Shift BigInt-এ নেই
// BigInt Arithmetic: console.log(10n + 3n); // → 13n console.log(10n - 3n); // → 7n console.log(10n * 3n); // → 30n console.log(10n / 3n); // → 3n ⚠️ (দশমিক নেই, floor হয়) console.log(10n % 3n); // → 1n console.log(2n ** 10n); // → 1024n // Increment / Decrement: let counter = 0n; counter++; console.log(counter); // → 1n // Bitwise BigInt-এ (>>> ছাড়া সব): console.log(5n & 3n); // → 1n console.log(5n | 3n); // → 7n console.log(5n ^ 3n); // → 6n console.log(~5n); // → -6n console.log(1n << 10n); // → 1024n console.log(1024n>> 2n); // → 256n

BigInt Comparison ও Mixed Operations Comparison

// Comparison — === type চেক করে: console.log(42n === 42); // → false (type আলাদা: bigint vs number) console.log(42n == 42); // → true (== coercion করে) console.log(42n === 42n); // → true // Relational — মিশিয়ে তুলনা করা যায়: console.log(10n > 5); // → true ✅ console.log(10n < 20); // → true ✅ console.log(5n>= 5); // → true ✅ // Sort-এ BigInt ও Number মেশানো: const mixed = [3n, 1, 2n, 4, 5n]; mixed.sort((a, b) => (a < b ? -1 : a> b ? 1 : 0)); // <> কাজ করে console.log(mixed); // → [1, 2n, 3n, 4, 5n] // ❌ Arithmetic-এ মেশানো যায় না: try { console.log(10n + 5); // TypeError! } catch (e) { console.log(e.message); // → Cannot mix BigInt and other types } // ✅ Convert করে মেশাও: console.log(10n + BigInt(5)); // → 15n console.log(Number(10n) + 5); // → 15 // BigInt → String: console.log(String(42n)); // → "42" console.log((42n).toString()); // → "42" console.log((255n).toString(16)); // → "ff" (hex) console.log((8n).toString(2)); // → "1000" (binary) // Practical — বড় সংখ্যার হিসাব (ক্রিপ্টোগ্রাফি, Factorial): function factorial(n) { if (n <= 1n) return 1n; return n * factorial(n - 1n); } console.log(factorial(20n)); // → 2432902008176640000n ✅ console.log(factorial(50n)); // → 30414093201713378043612608166979581188299763898377856000000000000n ✅

BigInt-এর সীমাবদ্ধতা সীমাবদ্ধতা

সীমাবদ্ধতা উদাহরণ সমাধান
Number-এর সাথে Arithmetic নেই 10n + 5 → TypeError 10n + BigInt(5)
দশমিক নেই 10n / 3n3n Float দরকার হলে Number ব্যবহার করো
Math Object-এ কাজ করে না Math.sqrt(9n) → TypeError Number() দিয়ে convert করো
Unary + নেই +42n → TypeError Number(42n)
JSON-এ serialize হয় না JSON.stringify(42n) → TypeError String-এ convert করো
>>> (Unsigned Shift) নেই 1n >>> 0n → TypeError >> ব্যবহার করো
BigInt কখন ব্যবহার করবে: ক্রিপ্টোগ্রাফিক হিসাব, Database-এর 64-bit Integer ID (Twitter Snowflake ID ইত্যাদি), Factorial ও Fibonacci-র বড় মান, Financial calculation যেখানে precision জরুরি। সাধারণ কাজে Number-ই যথেষ্ট।

🔷 Conditional Operators — শর্তভিত্তিক মান নির্বাচন

Conditional Operator হলো শর্তের ফলাফলের উপর ভিত্তি করে মান নির্বাচন করার Operator। JavaScript-এ একাধিক Conditional Operator আছে — প্রতিটির আলাদা উদ্দেশ্য ও ব্যবহার।

Conditional Operators-এর তুলনা Comparison

Operator নাম B বেছে নেয় কখন? ফাঁদ
cond ? A : B Ternary cond falsy হলে জটিল হলে পড়া কঠিন
A || B Logical OR A falsy হলে (0, "", false, null, undefined, NaN) 0 ও "" valid হলে সমস্যা
A ?? B Nullish Coalescing A শুধু null বা undefined হলে 0, "" ও false রক্ষা করে ✅
A?.B Optional Chaining A null/undefined হলে undefined Error ছাড়াই short-circuit
A && B Logical AND A truthy হলে B, A falsy হলে A Conditional execution-এ ব্যবহার

Ternary Operator (? :) — বিস্তারিত Ternary

// গঠন: condition ? valueIfTrue : valueIfFalse // ১. মৌলিক ব্যবহার: const age = 20; const label = age >= 18 ? "প্রাপ্তবয়স্ক" : "অপ্রাপ্তবয়স্ক"; console.log(label); // → প্রাপ্তবয়স্ক // ২. Template Literal-এ (if...else ব্যবহার করা যায় না এখানে): const score = 75; console.log(`ফলাফল: ${score >= 33 ? "পাস ✅" : "ফেল ❌"}`); // ৩. Function return-এ: const max = (a, b) => a > b ? a : b; console.log(max(10, 25)); // → 25 // ৪. Conditional rendering (React pattern): const isLoggedIn = true; const button = isLoggedIn ? "লগআউট" : "লগইন"; console.log(button); // → লগআউট // ৫. Default মান (সহজ ক্ষেত্রে): function greet(name) { return `হ্যালো, ${name ? name : "অতিথি"}!`; } console.log(greet("করিম")); // → হ্যালো, করিম! console.log(greet("")); // → হ্যালো, অতিথি! // ৬. Object property নির্বাচন: const type = "admin"; const permissions = { read: true, write: type === "admin" ? true : false, delete: type === "admin" ? true : false, }; console.log(permissions); // → { read: true, write: true, delete: true } // ❌ Nested Ternary — এড়িয়ে চলো: const m = 75; const g = m >= 80 ? "A+" : m >= 70 ? "A" : m >= 60 ? "A-" : "B"; // পড়া কঠিন // ✅ এর বদলে: function getGrade(m) { if (m >= 80) return "A+"; if (m >= 70) return "A"; if (m >= 60) return "A-"; return "B"; } console.log(getGrade(75)); // → A

Logical OR (||) — Default মানের Operator || Default

// || = প্রথম truthy মান ফেরত দেয়: // Falsy: false, 0, "", null, undefined, NaN // Default মান দেওয়া: function createUser(name, role) { name = name || "অজানা"; // name falsy হলে "অজানা" role = role || "viewer"; // role falsy হলে "viewer" return { name, role }; } console.log(createUser("করিম", "admin")); // → { name: "করিম", role: "admin" } console.log(createUser("", "")); // → { name: "অজানা", role: "viewer" } console.log(createUser()); // → { name: "অজানা", role: "viewer" } // ⚠️ কিন্তু 0 বা false valid হলে সমস্যা: function setVolume(vol) { const volume = vol || 50; // ⚠️ vol=0 দিলেও 50 পাবে! 0 falsy return volume; } console.log(setVolume(0)); // → 50 ⚠️ (0 valid কিন্তু পেলাম 50!) console.log(setVolume(30)); // → 30 ✅ // ✅ এ ক্ষেত্রে ?? ব্যবহার করো: function setVolumeFixed(vol) { const volume = vol ?? 50; // শুধু null/undefined হলে 50 return volume; } console.log(setVolumeFixed(0)); // → 0 ✅ console.log(setVolumeFixed(30)); // → 30 ✅

Nullish Coalescing (??) — নিরাপদ Conditional Operator ES2020

// ?? = শুধু null বা undefined হলে ডান দিক নেয়: // || বনাম ?? — পার্থক্য বোঝা: const values = [null, undefined, 0, "", false, NaN, "মান", 42]; for (const v of values) { const withOR = v || "ডিফল্ট"; const withNULL = v ?? "ডিফল্ট"; if (withOR !== withNULL) { console.log(`মান: ${JSON.stringify(v)}`); console.log(` || → "${withOR}"`); console.log(` ?? → "${withNULL}"`); } } // → মান: 0 → || "ডিফল্ট", ?? "0" // → মান: "" → || "ডিফল্ট", ?? "" // → মান: false → || "ডিফল্ট", ?? "false" // → মান: null → || একই, ?? একই (উভয়ই "ডিফল্ট") // Practical — Config object: function initApp(config = {}) { return { port: config.port ?? 3000, // 0 valid debug: config.debug ?? false, // false valid maxRetries: config.maxRetries ?? 3, // 0 valid (retry নেই) title: config.title ?? "MyApp", // "" valid (untitled) timeout: config.timeout ?? 5000, // 0 valid (no timeout) }; } console.log(initApp({ port: 0, debug: false, maxRetries: 0 })); // → { port: 0, debug: false, maxRetries: 0, title: "MyApp", timeout: 5000 } // ✅ 0 ও false সঠিকভাবে রাখা হয়েছে // Chained ??: const a = null; const b = undefined; const c = "পাওয়া গেছে"; console.log(a ?? b ?? c); // → "পাওয়া গেছে" (প্রথম non-nullish)

Optional Chaining (?.) — Conditional Property Access ES2020

// ?. = null/undefined হলে undefined, নইলে property/method/index access: // তিন ধরনের ব্যবহার: // ১. Property: obj?.prop // ২. Method: obj?.method() // ৩. Index: arr?.[i] const user = { name: "রাহেলা", address: { city: "ঢাকা" }, getName: () => "রাহেলা", }; // Property: console.log(user?.name); // → "রাহেলা" console.log(user?.address?.city); // → "ঢাকা" console.log(user?.address?.zip); // → undefined (নেই, Error নেই) console.log(user?.phone?.number); // → undefined (phone নেই) // Method: console.log(user?.getName?.()); // → "রাহেলা" console.log(user?.getAge?.()); // → undefined (method নেই, Error নেই) // Index: const items = ["ক", "খ", "গ"]; console.log(items?.[0]); // → "ক" console.log(items?.[10]); // → undefined const noItems = null; console.log(noItems?.[0]); // → undefined (Error নেই) // API Response-এ (বাস্তব ব্যবহার): async function getUserCity(userId) { const res = await fetch(`/api/users/${userId}`).catch(() => null); return res?.data?.profile?.address?.city ?? "শহর অজানা"; } // ?. ও ?? একসাথে — সবচেয়ে নিরাপদ pattern: const response = null; const name = response?.user?.name ?? "অতিথি"; const role = response?.user?.role?.toUpperCase?.() ?? "USER"; console.log(name, role); // → অতিথি USER

Logical AND (&&) — Conditional Execution Short-circuit

// && = প্রথম falsy মান ফেরত, নইলে শেষ মান। // Conditional execution-এ ব্যবহার: // ১. শর্তসাপেক্ষে function call: const isAdmin = true; isAdmin && showAdminPanel(); // isAdmin truthy → showAdminPanel() call হবে false && console.log("না চলবে"); // false → short-circuit, console call নেই // ২. শর্তসাপেক্ষে property access: const user = { name: "করিম", isVerified: true }; const badge = user.isVerified && "✅ যাচাইকৃত"; console.log(badge); // → "✅ যাচাইকৃত" const guest = { name: "অতিথি", isVerified: false }; const guestBadge = guest.isVerified && "✅ যাচাইকৃত"; console.log(guestBadge); // → false (isVerified falsy) // ৩. React-style Conditional Rendering: const count = 5; const message = count > 0 && `${count}টি নতুন বার্তা`; console.log(message); // → "5টি নতুন বার্তা" const emptyCount = 0; const emptyMessage = emptyCount > 0 && `${emptyCount}টি নতুন বার্তা`; console.log(emptyMessage); // → false (React-এ render হয় না) // ৪. একাধিক শর্ত: const hasPermission = true; const isActive = true; const canEdit = hasPermission && isActive && "সম্পাদনা করুন"; console.log(canEdit); // → "সম্পাদনা করুন"

Conditional Operator বেছে নেওয়ার নিয়ম Decision Guide

পরিস্থিতি ব্যবহার করো কারণ
দুটো মানের মধ্যে সিদ্ধান্ত condition ? a : b স্পষ্ট দুটো বিকল্প, Template Literal-এও কাজ করে
null/undefined হলে fallback val ?? default 0, false, "" রক্ষা পায়
falsy হলে fallback (0 ও "" invalid) val || default সব falsy মান বাদ দেয়
Nested property নিরাপদে পড়া obj?.a?.b?.c TypeError ছাড়াই undefined পায়
শর্তসাপেক্ষে কাজ করানো cond && action() if ছাড়া এক লাইনে
null/undefined + fallback একসাথে obj?.prop ?? "ডিফল্ট" ?. ও ?? মিলিয়ে সবচেয়ে নিরাপদ
জটিল শর্ত, ৩+ বিকল্প if...else if Nested ternary পড়া কঠিন

🔷 দ্রুত রেফারেন্স — Expressions and Operators সম্পূর্ণ

কোন Operator কখন ব্যবহার করবে? Decision Guide

পরিস্থিতি সেরা পছন্দ কারণ
মান সমান কিনা তুলনা === Type-safe — সবসময় এটাই ব্যবহার করো
Variable-এর type জানা typeof String হিসেবে type দেয়
Object-এর class জানা instanceof Prototype chain চেক করে
Array কিনা চেক Array.isArray() typeof [] = "object", instanceof iframe-এ সমস্যা
Object-এ property আছে কিনা in বা hasOwn in = prototype সহ, hasOwn = নিজের শুধু
null/undefined হলে fallback ?? 0, "" রক্ষা করে
Nested property নিরাপদে ?. TypeError ছাড়াই undefined পায়
Array copy/merge Spread ... সহজ, immutable pattern
String জোড়া লাগানো Template Literal + Concatenation-এর চেয়ে পরিষ্কার
Permission/Flag check Bitwise & | দ্রুত, মেমোরি সাশ্রয়ী

সাধারণ ভুল ও সমাধান Common Mistakes

ভুল কোড সমস্যা সঠিক কোড
x == y Type Coercion — অপ্রত্যাশিত ফলাফল x === y
1 + "2" → "12" (String concat!) 1 + Number("2") বা 1 + +"2"
typeof null === "null" typeof null = "object" (bug!) val === null
typeof [] === "array" typeof [] = "object" Array.isArray([])
delete arr[i] Hole তৈরি হয়, length অপরিবর্তিত arr.splice(i, 1)
count || default (count=0) 0 falsy — default পাবে count ?? default
"10" > "9" → false (String তুলনা!) Number("10") > Number("9")
(-2) ** 2 লিখতে ভুলে -2 ** 2 SyntaxError — unary minus-এ () লাগে (-2) ** 2 বা Math.pow(-2, 2)

সব Operators এক নজরে Quick Reference

ধরন Operators
Assignment = += -= *= /= %= **= &&= ||= ??=
Arithmetic + - * / % ** ++ --
Comparison == === != !== > < >= <=
Logical && || ! ??
Bitwise & | ^ ~ << >> >>>
String + += Template Literal ``
Unary typeof void delete ! +x -x ++ --
Relational instanceof in
Ternary ? :
Optional / Nullish ?. ?? ??=
Spread / Rest ...
Comma ,
BigInt + - * / % ** ++ -- & | ^ ~ << >> (n suffix)
Conditional ? : || ?? ?. &&

🧠 নিজেকে যাচাই করো

1. ** operator কী করে?

2. && operator কখন true?

3. ?? (nullish coalescing) কী?

✏️ Task — এখন তুমি করো

Calculator বানাও — +, -, *, /, % সব operator ব্যবহার করো।

ধাপ 9🏗️ Real Project — Interactive Portfolio

Portfolio-এ BMI calculator বানাও — operators ব্যবহার করো।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio-এ dark/light mode toggle বানাও।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

⚙️ JavaScript Functions — সম্পূর্ণ নোট

এই সেকশনে JavaScript-এর Functions-এর সব দিক — Function Declaration, Expression, Arrow Function, Parameters, Scope, Lexical Scoping, Function Stack, Closure, Higher-Order Functions, Recursion, Built-in Functions — বাংলায় উদাহরণসহ বিস্তারিত আলোচনা করা হয়েছে।


🔷 Function কী ও কেন প্রয়োজন?

Function হলো একটি নামযুক্ত পুনর্ব্যবহারযোগ্য কোড-ব্লক। একবার লিখে যতবার খুশি ডাকা যায়। Function ছাড়া বড় প্রোগ্রাম লেখা প্রায় অসম্ভব — কারণ একই কোড বারবার লিখতে হতো।

সহজ উদাহরণ — একটি ক্লাসের ৪০ জন ছাত্রের গ্রেড বের করতে একটি getGrade() function একবার লিখলেই হয়, ৪০ বার আলাদা করে কোড লিখতে হয় না।

Function-এর ধরন Syntax বিশেষত্ব ES Version
Function Declaration function name() {} Hoisted — ঘোষণার আগেই ডাকা যায় ES1
Function Expression const f = function() {} Hoisted নয় — ঘোষণার পরে ডাকতে হবে ES1
Arrow Function const f = () => {} নিজস্ব this নেই, সংক্ষিপ্ত ES6
Named Function Expression const f = function name() {} Recursion ও debugging-এ সুবিধা ES1
IIFE (function() {})() তাৎক্ষণিক চালু, scope দূষণ নেই ES1
Generator Function function* name() {} yield দিয়ে pause/resume করা যায় ES6
Async Function async function name() {} await ব্যবহার করে async কাজ সহজ ES2017

🔷 Function Declaration ও Function Expression

Function Declaration Declaration

// গঠন: function functionName(parameters) { body } // ১. সাধারণ Function Declaration: function greet(name) { return `আস-সালামু আলাইকুম, ${name}!`; } console.log(greet("করিম")); // → আস-সালামু আলাইকুম, করিম! // ২. Hoisting — ঘোষণার আগেই call করা যায়: console.log(add(5, 3)); // → 8 ✅ (hoisted!) function add(a, b) { return a + b; } // ৩. Multiple return paths: function getGrade(marks) { if (marks >= 80) return "A+"; if (marks >= 70) return "A"; if (marks >= 60) return "A-"; if (marks >= 50) return "B"; if (marks >= 33) return "C"; return "F"; } console.log(getGrade(85)); // → A+ console.log(getGrade(45)); // → B console.log(getGrade(20)); // → F // ৪. Return ছাড়া — undefined ফেরত: function printHello() { console.log("হ্যালো!"); // return নেই } const result = printHello(); // → হ্যালো! console.log(result); // → undefined

Function Expression Expression

// সাধারণ Function Expression: const multiply = function(a, b) { return a * b; }; console.log(multiply(4, 5)); // → 20 // ❌ Hoisting নেই — আগে call করলে Error: // console.log(square(5)); // → ReferenceError (TDZ) const square = function(x) { return x * x; }; console.log(square(5)); // → 25 ✅ // Named Function Expression — নামটি শুধু function-এর ভেতরে দৃশ্যমান: const factorial = function fact(n) { if (n <= 1) return 1; return n * fact(n - 1); // নিজেকে 'fact' নামে ডাকছে }; console.log(factorial(5)); // → 120 // console.log(fact(5)); // → ReferenceError (বাইরে 'fact' নেই) // Function Expression-কে Argument হিসেবে পাঠানো: const numbers=[5, 2, 8, 1, 9, 3]; numbers.sort(function(a, b) { return a - b; }); console.log(numbers); // → [1, 2, 3, 5, 8, 9]

Declaration বনাম Expression — পার্থক্য Comparison

বিষয় Function Declaration Function Expression
Hoisting ✅ সম্পূর্ণ Hoisted ❌ Hoisted নয় (TDZ)
ঘোষণার আগে call ✅ সম্ভব ❌ ReferenceError
নাম অবশ্যই নাম দিতে হবে নাম ঐচ্ছিক (anonymous হতে পারে)
Conditional-এ ⚠️ Strict Mode-এ সীমাবদ্ধতা ✅ if-এর ভেতরেও define করা যায়
ব্যবহার Top-level utility functions Callback, Higher-order, Conditional

🔷 Arrow Functions — সংক্ষিপ্ত Function Syntax

Arrow Function হলো ES6-এর সংক্ষিপ্ত function syntax। শুধু syntax-ই ছোট নয় — নিজস্ব this নেই, বাইরের context-এর this ব্যবহার করে। এটিই Regular Function-এর সাথে মূল পার্থক্য।

Arrow Function-এর বিভিন্ন রূপ Syntax

// পূর্ণ রূপ: const greet = (name) => { return `হ্যালো, ${name}!`; }; // একটি parameter হলে () বাদ দেওয়া যায়: const double = x => x * 2; console.log(double(5)); // → 10 // একটি expression হলে {} ও return বাদ: const add = (a, b) => a + b; console.log(add(3, 4)); // → 7 // Parameter নেই: const greetAll = () => "সবাইকে হ্যালো!"; console.log(greetAll()); // → সবাইকে হ্যালো! // Object ফেরত দিলে () দিয়ে wrap করতে হবে: const makeUser = (name, age) => ({ name, age }); console.log(makeUser("করিম", 25)); // → { name: "করিম", age: 25 } // ⚠️ {} ছাড়া: (name, age) => { name, age } — এটা body হিসেবে নেয়, Object নয়! // Multi-line Arrow Function: const processOrder = (items) => { const total = items.reduce((sum, item) => sum + item.price, 0); const tax = total * 0.05; return { total, tax, grandTotal: total + tax }; }; console.log(processOrder([ { name: "চাল", price: 650 }, { name: "ডাল", price: 120 }, ])); // → { total: 770, tax: 38.5, grandTotal: 808.5 }

Arrow Function বনাম Regular Function — this-এর পার্থক্য this Context

// Regular Function-এ this = caller: const timer1 = { seconds: 0, start: function() { setInterval(function() { this.seconds++; // ⚠️ this = global/undefined (caller হলো setInterval) console.log(this.seconds); // → NaN বা Error }, 1000); } }; // Arrow Function-এ this = Lexical (define করার জায়গার this): const timer2 = { seconds: 0, start: function() { setInterval(() => { this.seconds++; // ✅ this = timer2 (arrow function lexical this নেয়) console.log(this.seconds); // → 1, 2, 3... }, 1000); } }; // Class-এ: class Counter { constructor() { this.count = 0; } // Regular Method — this সঠিক: increment() { this.count++; return this.count; } // Arrow Function হিসেবে method (class field): decrement = () => { this.count--; return this.count; }; // Regular Function-এ Callback সমস্যা: badDelay() { setTimeout(function() { this.count++; // ⚠️ this = undefined (strict mode) বা global }, 100); } // Arrow Function-এ Callback সঠিক: goodDelay() { setTimeout(() => { this.count++; // ✅ this = Counter instance }, 100); } } // Arrow Function-এ যা নেই: // ১. নিজস্ব this নেই // ২. arguments object নেই // ৩. Constructor হিসেবে ব্যবহার যায় না (new দিয়ে) // ৪. prototype property নেই const ArrowFn = () => {}; // new ArrowFn(); // → TypeError: ArrowFn is not a constructor

Arrow ও Regular Function — কখন কোনটা? Decision Guide

পরিস্থিতি ব্যবহার করো কারণ
Callback (map, filter, forEach) Arrow Function সংক্ষিপ্ত, this সমস্যা নেই
Event Handler-এ this দরকার Regular Function Arrow-এ this = outer, element পাওয়া যাবে না
Object Method Regular Function (shorthand) this = object দরকার
Class Method (setTimeout সহ) Arrow Function (class field) this bind সমস্যা এড়ায়
Constructor Function Regular Function বা Class Arrow Function constructor হয় না
Top-level utility function Function Declaration Hoisting সুবিধা, পরিষ্কার

🔷 Parameters ও Arguments — বিস্তারিত

Parameter হলো function definition-এর placeholder নাম। Argument হলো function call-এর সময় দেওয়া আসল মান। JavaScript-এ parameter-এর চেয়ে বেশি বা কম argument দেওয়া যায় — কোনো Error হয় না।

Default Parameters — ES6 Default

// Default Parameter: function greet(name = "অতিথি", greeting = "আস-সালামু আলাইকুম") { return `${greeting}, ${name}!`; } console.log(greet("করিম", "হ্যালো")); // → হ্যালো, করিম! console.log(greet("রাহেলা")); // → আস-সালামু আলাইকুম, রাহেলা! console.log(greet()); // → আস-সালামু আলাইকুম, অতিথি! console.log(greet(undefined, "হাই")); // → হাই, অতিথি! (undefined → default) console.log(greet(null, "হাই")); // → হাই, null! (null ≠ undefined) // Default-এ Expression: function createId(prefix = "ID", num = Date.now()) { return `${prefix}-${num}`; } // Default-এ আগের Parameter ব্যবহার: function makeRect(width, height = width) { // height না দিলে square return { width, height, area: width * height }; } console.log(makeRect(5)); // → { width: 5, height: 5, area: 25 } console.log(makeRect(5, 3)); // → { width: 5, height: 3, area: 15 } // ⚠️ Default Parameter-এর পরে Non-default রাখো না: // function bad(a = 1, b) {} // b-কে দিতে হলে a-ও দিতে হবে — বিভ্রান্তিকর

Rest Parameters (...args) Rest

// Rest Parameter — বাকি সব argument একটি Array-এ: function sum(...numbers) { return numbers.reduce((total, n) => total + n, 0); } console.log(sum(1, 2, 3)); // → 6 console.log(sum(1, 2, 3, 4, 5)); // → 15 console.log(sum()); // → 0 // প্রথম কিছু আলাদা করে, বাকি Rest-এ: function log(level, ...messages) { const prefix = `[${level.toUpperCase()}]`; messages.forEach(msg => console.log(`${prefix} ${msg}`)); } log("info", "সার্ভার চালু", "Port: 3000"); // → [INFO] সার্ভার চালু // → [INFO] Port: 3000 log("error", "Connection failed"); // → [ERROR] Connection failed // ⚠️ Rest parameter সবসময় শেষে থাকে: // function bad(...a, b) {} // SyntaxError! function good(first, second, ...rest) { console.log(first, second, rest); } good(1, 2, 3, 4, 5); // → 1 2 [3, 4, 5]

Destructuring Parameters — Object ও Array Destructuring

// Object Destructuring Parameter: function displayUser({ name, age, city = "অজানা" }) { console.log(`${name} (${age}) — ${city}`); } displayUser({ name: "রাহেলা", age: 22, city: "ঢাকা" }); // → রাহেলা (22) — ঢাকা displayUser({ name: "করিম", age: 25 }); // → করিম (25) — অজানা // Rename করে নেওয়া: function connect({ host: server, port: portNum = 3000 }) { return `${server}:${portNum}`; } console.log(connect({ host: "localhost" })); // → localhost:3000 console.log(connect({ host: "api.bd", port: 8080 })); // → api.bd:8080 // Array Destructuring Parameter: function getFirst([first, second, ...rest]) { return { first, second, rest }; } console.log(getFirst([10, 20, 30, 40])); // → { first: 10, second: 20, rest: [30, 40] } // Nested Destructuring: function processOrder({ user: { name }, items: [firstItem] }) { return `${name}-এর প্রথম অর্ডার: ${firstItem.name}`; } console.log(processOrder({ user: { name: "করিম" }, items: [{ name: "চাল", qty: 5 }, { name: "ডাল", qty: 2 }] })); // → করিম-এর প্রথম অর্ডার: চাল

arguments Object — পুরানো পদ্ধতি Legacy

// arguments Object (Regular Function-এ): function oldSum() { let total = 0; for (let i = 0; i < arguments.length; i++) { total +=arguments[i]; } return total; } console.log(oldSum(1, 2, 3, 4)); // → 10 // arguments Array-like কিন্তু Array নয়: function test() { console.log(typeof arguments); // → object console.log(Array.isArray(arguments)); // → false ⚠️ // arguments.forEach(...) → TypeError! // Array-এ convert করতে: const args=Array.from(arguments); // বা: const args=[...arguments]; args.forEach(a=> console.log(a)); } // ✅ আধুনিক পদ্ধতি — Rest Parameter: const modernSum = (...nums) => nums.reduce((a, b) => a + b, 0); console.log(modernSum(1, 2, 3, 4)); // → 10

🔷 Scope, Function Stack ও Lexical Scoping

Scope নির্ধারণ করে কোন variable বা function কোথা থেকে access করা যাবে। Lexical Scoping মানে এই Scope কোড লেখার সময় নির্ধারিত হয় — চালানোর সময় নয়। আর Function Stack হলো JavaScript Engine কোন function কোন ক্রমে চালাচ্ছে তার memory-র স্তূপ।

Scope-এর ধরন — Global, Function, Block Scope

// ১. Global Scope — সবখান থেকে access যায়: const globalVar = "আমি global"; function showGlobal() { console.log(globalVar); // → আমি global ✅ (ভেতর থেকে বাইরের variable) } showGlobal(); console.log(globalVar); // → আমি global ✅ // ২. Function (Local) Scope — শুধু function-এর ভেতরে: function myFunction() { const localVar = "আমি local"; console.log(localVar); // → আমি local ✅ } myFunction(); // console.log(localVar); // → ReferenceError ❌ (বাইরে নেই) // ৩. Block Scope — {} ব্লকের ভেতরে (let/const): { let blockLet = "let block-এ"; const blockConst = "const block-এ"; var blockVar = "var leak!"; // ⚠️ var Block-scoped নয়! } // console.log(blockLet); // → ReferenceError ❌ // console.log(blockConst); // → ReferenceError ❌ console.log(blockVar); // → "var leak!" ⚠️ (বাইরেও দেখা যাচ্ছে!) // ৪. Scope chain — ভেতর থেকে বাইরে দেখা যায়, বাইরে থেকে ভেতরে নয়: const level1 = "স্তর ১"; function outer() { const level2 = "স্তর ২"; function middle() { const level3 = "স্তর ৩"; function inner() { const level4 = "স্তর ৪"; console.log(level1); // ✅ উপরের সব স্তর দেখা যায় console.log(level2); // ✅ console.log(level3); // ✅ console.log(level4); // ✅ নিজের স্তর } inner(); // console.log(level4); // ❌ নিচের স্তর দেখা যায় না } middle(); } outer();

Lexical Scoping — কোড লেখার সময়েই Scope নির্ধারিত Lexical

// Lexical Scoping — define করার জায়গার Scope: const language = "বাংলা"; function greet() { // language এখানে define করা হয়নি, কিন্তু Lexical Scope থেকে পাবে: console.log(`ভাষা: ${language}`); } function changeContext() { const language = "English"; // এটা greet()-এর Scope-এ পৌঁছায় না greet(); // greet() তার define করার সময়ের Scope ব্যবহার করে } greet(); // → ভাষা: বাংলা ✅ (global language) changeContext(); // → ভাষা: বাংলা ✅ (changeContext-এর language নয়!) // ব্যাখ্যা: greet() যেখানে define হয়েছে, সেখানে language = "বাংলা"। // changeContext() যেখানে call হয়েছে সেটা Scope বদলায় না। // আরেকটি উদাহরণ: function makeGreeter(greeting) { return function(name) { // greeting — define করার সময়ের Lexical Scope থেকে পাওয়া: return `${greeting}, ${name}!`; }; } const greetBangla = makeGreeter("আস-সালামু আলাইকুম"); const greetEnglish = makeGreeter("Hello"); // এই দুটো function যেখানেই call করো, Scope বদলায় না: console.log(greetBangla("করিম")); // → আস-সালামু আলাইকুম, করিম! console.log(greetEnglish("Karim")); // → Hello, Karim! // Dynamic Scoping (JavaScript-এ নেই, তুলনার জন্য): // Dynamic হলে call করার সময়ের Scope দেখত — JavaScript-এ এটা হয় না। // JavaScript সবসময় Lexical (Static) Scoping ব্যবহার করে।

Scope Chain — Variable খোঁজার ক্রম Scope Chain

// Scope Chain — নিচ থেকে উপরে খোঁজে: const x = "global x"; function outer() { const x = "outer x"; // global x কে shadow করেছে const y = "outer y"; function inner() { const z = "inner z"; // x খুঁজছে: inner → outer (পেয়ে গেল "outer x"): console.log(x); // → "outer x" (outer-এর x) console.log(y); // → "outer y" console.log(z); // → "inner z" } inner(); console.log(x); // → "outer x" (outer-এর x) } outer(); console.log(x); // → "global x" (global-এর x) // Shadowing — একই নামে ভেতরে নতুন variable: const name = "গ্লোবাল নাম"; function showName() { const name = "লোকাল নাম"; // global name-কে shadow করেছে console.log(name); // → "লোকাল নাম" } showName(); console.log(name); // → "গ্লোবাল নাম" (global-এর name অপরিবর্তিত)

Function Stack (Call Stack) — Function চালানোর স্তূপ Call Stack

// Call Stack-এর কাজ দেখা: function third() { console.log("third শুরু"); // এখন Stack: [main, first, second, third] console.log("third শেষ"); } function second() { console.log("second শুরু"); third(); // third-কে call → Stack-এ push // third শেষ হয়ে Stack থেকে pop হয়ে গেছে console.log("second শেষ"); } function first() { console.log("first শুরু"); second(); // second-কে call → Stack-এ push console.log("first শেষ"); } first(); // আউটপুট ক্রম: // → first শুরু // → second শুরু // → third শুরু // → third শেষ (pop) // → second শেষ (pop) // → first শেষ (pop) // Error-এর Stack Trace — Call Stack দেখায়: function alpha() { beta(); } function beta() { gamma(); } function gamma() { throw new Error("এখানে Error হয়েছে!"); } try { alpha(); } catch (e) { console.log(e.stack); // → Error: এখানে Error হয়েছে! // at gamma (file.js:3) ← সবচেয়ে ভেতরে // at beta (file.js:2) // at alpha (file.js:1) ← সবচেয়ে বাইরে } // Stack Overflow — অসীম Recursion: function infinite() { return infinite(); // Base Case নেই! } try { infinite(); } catch (e) { console.log(e.message); // → Maximum call stack size exceeded }

Call Stack-এ Recursion-এর চিত্র Visualization

// factorial(3) চালালে Call Stack কীভাবে কাজ করে: function factorial(n) { if (n <= 1) return 1; return n * factorial(n - 1); } // factorial(3) call করলে Stack-এর পরিবর্তন: // // ধাপ ১: factorial(3) push → Stack: [factorial(3)] // n=3, 3 * factorial(2) call করবে // // ধাপ ২: factorial(2) push → Stack: [factorial(3), factorial(2)] // n=2, 2 * factorial(1) call করবে // // ধাপ ৩: factorial(1) push → Stack: [factorial(3), factorial(2), factorial(1)] // n=1, Base Case! return 1 // // ধাপ ৪: factorial(1) pop → Stack: [factorial(3), factorial(2)] // factorial(2) পায় 1, return 2*1=2 // // ধাপ ৫: factorial(2) pop → Stack: [factorial(3)] // factorial(3) পায় 2, return 3*2=6 // // ধাপ ৬: factorial(3) pop → Stack: [] // চূড়ান্ত ফলাফল: 6 console.log(factorial(3)); // → 6 // Stack depth পরীক্ষা করা: let maxDepth=0; function measureDepth(n, depth=0) { maxDepth=Math.max(maxDepth, depth); if (n <=0) return 0; return measureDepth(n - 1, depth + 1); } measureDepth(100); console.log("সর্বোচ্চ depth:", maxDepth); // → সর্বোচ্চ depth: 100

Hoisting — Declaration উপরে ওঠানো Hoisting

// ===== Function Declaration — সম্পূর্ণ Hoisted ===== console.log(sayHello()); // → হ্যালো! ✅ (ঘোষণার আগেই call!) function sayHello() { return "হ্যালো!"; } // ===== var — Hoisted কিন্তু undefined ===== console.log(a); // → undefined ⚠️ (Error নেই কিন্তু মান নেই) var a = 10; console.log(a); // → 10 // ===== let/const — Hoisted কিন্তু TDZ (Temporal Dead Zone) ===== // console.log(b); // → ReferenceError: Cannot access 'b' before initialization let b = 20; console.log(b); // → 20 // ===== Function Expression — Hoisted নয় ===== // console.log(myFn()); // → ReferenceError (TDZ) const myFn = function() { return "আমি function expression"; }; console.log(myFn()); // → আমি function expression ✅ // JavaScript Engine আসলে এভাবে দেখে: // ↓ function declaration উপরে উঠে যায় // function sayHello() { return "হ্যালো!"; } // ↓ var declaration উপরে ওঠে (undefined দিয়ে) // var a; // = undefined // ↓ let/const TDZ-এ থাকে (access নিষিদ্ধ) // console.log(sayHello()); // ✅ উপরে উঠে গেছে // console.log(a); // undefined // a = 10; // এখানে assignment
⚠️ var এড়িয়ে চলো: var-এর Function-scoped ও Hoisting আচরণ অনেক বাগের কারণ। সবসময় letconst ব্যবহার করো। const সর্বোচ্চ প্রাধান্য দাও — পরিবর্তন দরকার হলে let

🔷 Closure — Lexical Scoping-এর ফল

Closure হলো Lexical Scoping-এর প্রত্যক্ষ ফল। একটি inner function তার Lexical Environment সহ return হয় — অর্থাৎ বাইরের function-এর variable মনে রাখে, এমনকি outer function Call Stack থেকে চলে যাওয়ার পরেও।

Closure কীভাবে কাজ করে How it works

// ধাপে ধাপে Closure বোঝা: // ১. Outer function একটি variable ও inner function define করে: function outerFunction(outerVar) { // outerVar = "বাইরের মান" — Lexical Scope-এ আছে function innerFunction(innerVar) { // Lexical Scoping: outerVar এখানেও দৃশ্যমান console.log(`বাইরের: ${outerVar}, ভেতরের: ${innerVar}`); } return innerFunction; // inner function তার Lexical Environment-সহ return } // ২. outerFunction call করলে inner function পাওয়া যায়: const myFunc = outerFunction("বাইরের মান"); // outerFunction এখন Call Stack থেকে চলে গেছে! // কিন্তু outerVar মেমোরিতে আছে — কারণ myFunc এখনো ব্যবহার করছে। // ৩. inner function call করলে outerVar মনে আছে: myFunc("ভেতরের মান"); // → বাইরের: বাইরের মান, ভেতরের: ভেতরের মান ✅ // Closure-এর মেমোরি মডেল: // myFunc → { function body, [[Environment]]: { outerVar: "বাইরের মান" } } // ↑ function নিজে ↑ Lexical Environment সংরক্ষিত // প্রতিটি call-এ আলাদা Closure: const func1 = outerFunction("প্রথম"); const func2 = outerFunction("দ্বিতীয়"); func1("ক"); // → বাইরের: প্রথম, ভেতরের: ক func2("খ"); // → বাইরের: দ্বিতীয়, ভেতরের: খ // func1 ও func2 আলাদা Closure — আলাদা outerVar!

Closure দিয়ে Private State Private State

// Counter — Closure দিয়ে Private State: function createCounter(initialValue = 0) { let count = initialValue; // count বাইরে থেকে সরাসরি access করা যাবে না — এটাই encapsulation return { increment() { return ++count; }, decrement() { return --count; }, reset() { count = initialValue; return count; }, getCount() { return count; }, }; // উপরের সব method একই Lexical Environment share করে // তাই সবাই একই count দেখতে পায় } const counter1 = createCounter(10); const counter2 = createCounter(0); // আলাদা Closure — আলাদা count console.log(counter1.increment()); // → 11 console.log(counter1.increment()); // → 12 console.log(counter2.increment()); // → 1 (counter1-এ কোনো প্রভাব নেই) console.log(counter1.getCount()); // → 12 console.log(counter1.reset()); // → 10 // console.log(count); // → ReferenceError ✅ (বাইরে access নেই)

Closure-এর Practical ব্যবহার Practical

// ১. Factory Function — বিভিন্ন ধরনের function তৈরি: function multiplier(factor) { return (number) => number * factor; // factor Closure-এ আটকা } const double = multiplier(2); const triple = multiplier(3); const tenTimes = multiplier(10); console.log(double(5)); // → 10 console.log(triple(5)); // → 15 console.log(tenTimes(5)); // → 50 // ২. Memoization — ফলাফল Cache করা: function memoize(fn) { const cache = new Map(); // cache Closure-এ আটকা — প্রতিটি call-এ টিকে থাকে return function(...args) { const key = JSON.stringify(args); if (cache.has(key)) { console.log("Cache থেকে পাওয়া!"); return cache.get(key); } const result = fn(...args); cache.set(key, result); return result; }; } const slowSquare = (n) => n * n; const fastSquare = memoize(slowSquare); console.log(fastSquare(10)); // → 100 (হিসাব হলো) console.log(fastSquare(10)); // → 100 (Cache থেকে!) console.log(fastSquare(20)); // → 400 (হিসাব হলো) // ৩. Partial Application — কিছু argument আগেই দেওয়া: function greetWith(greeting) { return (name) => `${greeting}, ${name}!`; // greeting Closure-এ } const greetBangla = greetWith("আস-সালামু আলাইকুম"); const greetEnglish = greetWith("Hello"); console.log(greetBangla("করিম")); // → আস-সালামু আলাইকুম, করিম! console.log(greetEnglish("Karim")); // → Hello, Karim!

Closure-এর সাধারণ ভুল — Loop-এ সাবধান

// ❌ var দিয়ে Loop-এ Closure সমস্যা: const funcsVar = []; for (var i = 0; i < 3; i++) { funcsVar.push(function() { return i; }); // প্রতিটি function একই i-কে Closure-এ রাখছে (var function-scoped) } // loop শেষে i=3 console.log(funcsVar[0]()); // → 3 ⚠️ (0 নয়!) console.log(funcsVar[1]()); // → 3 ⚠️ console.log(funcsVar[2]()); // → 3 ⚠️ // ✅ সমাধান ১ — let ব্যবহার (প্রতিটি iteration-এ নতুন Lexical Scope): const funcsLet=[]; for (let i=0; i < 3; i++) { funcsLet.push(function() { return i; }); // let block-scoped — প্রতিটি iteration-এ আলাদা i তৈরি হয় } console.log(funcsLet[0]()); // → 0 ✅ console.log(funcsLet[1]()); // → 1 ✅ console.log(funcsLet[2]()); // → 2 ✅ // ✅ সমাধান ২ — IIFE দিয়ে Closure capture: const funcsIIFE=[]; for (var j=0; j < 3; j++) { funcsIIFE.push( (function(capturedJ) { return function() { return capturedJ; }; // capturedJ আলাদা Closure })(j) ); } console.log(funcsIIFE[0]()); // → 0 ✅ console.log(funcsIIFE[1]()); // → 1 ✅ console.log(funcsIIFE[2]()); // → 2 ✅
Closure = Lexical Scoping + Function Return। প্রতিটি Function তৈরির সময় তার Lexical Environment-এর একটি reference রাখে। এই reference-টিই হলো Closure। Garbage Collector Closure-এর variable মুছে ফেলে না যতক্ষণ function জীবিত আছে।

🔷 Higher-Order Functions — Function যা Function নিয়ে কাজ করে

Higher-Order Function (HOF) হলো এমন function যা অন্য function-কে argument হিসেবে নেয় অথবা function ফেরত দেয়। JavaScript-এ function হলো "First-class citizen" — variable-এ রাখা, argument হিসেবে পাঠানো, ফেরত দেওয়া সব সম্ভব।

HOF-এর মূল উদাহরণ Examples

// ১. Callback Function — argument হিসেবে Function পাঠানো: function doTwice(fn, value) { return fn(fn(value)); // fn কে দুবার call করো } const addTen = x => x + 10; console.log(doTwice(addTen, 5)); // → 25 (5+10=15, 15+10=25) // ২. Function ফেরত দেওয়া: function makeAdder(x) { return y => x + y; // x মনে রাখা Closure } const add5 = makeAdder(5); const add10 = makeAdder(10); console.log(add5(3)); // → 8 console.log(add10(3)); // → 13 // ৩. Built-in HOF — Array methods: const students = [ { name: "করিম", score: 85, passed: true }, { name: "রাহেলা", score: 92, passed: true }, { name: "সজল", score: 45, passed: false }, { name: "নিলু", score: 78, passed: true }, { name: "আরিফ", score: 30, passed: false }, ]; // map — রূপান্তর: const names = students.map(s => s.name); console.log(names); // → ["করিম", "রাহেলা", "সজল", "নিলু", "আরিফ"] // filter — ছেঁকে নেওয়া: const passed = students.filter(s => s.passed); console.log(passed.length); // → 3 // reduce — একটিতে সংকুচিত: const totalScore = students.reduce((sum, s) => sum + s.score, 0); console.log(totalScore / students.length); // → 66 (গড়) // Method chaining — একসাথে: const topStudentNames = students .filter(s => s.score >= 80) .sort((a, b) => b.score - a.score) .map(s => `${s.name} (${s.score})`); console.log(topStudentNames); // → ["রাহেলা (92)", "করিম (85)"]

নিজের HOF তৈরি Custom HOF

// ১. নিজের forEach তৈরি: function myForEach(array, callback) { for (let i = 0; i < array.length; i++) { callback(array[i], i, array); } } myForEach([1, 2, 3], (item, index)=> { console.log(`${index}: ${item}`); }); // ২. নিজের map তৈরি: function myMap(array, transform) { const result = []; for (const item of array) { result.push(transform(item)); } return result; } console.log(myMap([1, 2, 3], x => x * x)); // → [1, 4, 9] // ৩. Function Composition — একাধিক function ক্রমে চালানো: function compose(...fns) { return (value) => fns.reduceRight((acc, fn) => fn(acc), value); } const double = x => x * 2; const addOne = x => x + 1; const square = x => x * x; const transform = compose(double, addOne, square); // right to left // square(5)=25, addOne(25)=26, double(26)=52 console.log(transform(5)); // → 52 // ৪. pipe — left to right composition: function pipe(...fns) { return (value) => fns.reduce((acc, fn) => fn(acc), value); } const process = pipe(square, addOne, double); // square(5)=25, addOne(25)=26, double(26)=52 console.log(process(5)); // → 52 // ৫. once — শুধু একবার চলবে: function once(fn) { let called = false; let result; return function(...args) { if (!called) { called = true; result = fn(...args); } return result; }; } const initDB = once(() => { console.log("Database initialize হচ্ছে..."); return "connected"; }); console.log(initDB()); // → Database initialize হচ্ছে... → connected console.log(initDB()); // → connected (আর initialize হয়নি!)

🔷 Recursion — Function যে নিজেকে ডাকে

Recursion হলো function-এর নিজেকে নিজে call করার পদ্ধতি। দুটো অংশ অবশ্যই থাকতে হবে — Base Case (থামার শর্ত) এবং Recursive Case (নিজেকে ডাকার শর্ত)।

Recursion-এর মূল উদাহরণ Examples

// ১. Factorial: function factorial(n) { if (n <= 1) return 1; // Base Case return n * factorial(n - 1); // Recursive Case } console.log(factorial(5)); // → 120 (5×4×3×2×1) console.log(factorial(10)); // → 3628800 // ২. Fibonacci: function fibonacci(n) { if (n <=1) return n; // Base Case return fibonacci(n - 1) + fibonacci(n - 2); // Recursive Case } console.log(fibonacci(10)); // → 55 // ৩. Sum of Array (Recursion দিয়ে): function arraySum(arr) { if (arr.length===0) return 0; // Base Case return arr[0] + arraySum(arr.slice(1)); // Recursive Case } console.log(arraySum([1, 2, 3, 4, 5])); // → 15 // ৪. Countdown: function countdown(n) { if (n < 0) return; // Base Case console.log(n); countdown(n - 1); // Recursive Case } countdown(5); // → 5, 4, 3, 2, 1, 0

Recursion-এর Practical ব্যবহার — Tree Traversal Tree

// DOM-এর মতো Nested Object traverse করা: const fileSystem = { name: "root", type: "folder", children: [ { name: "documents", type: "folder", children: [ { name: "resume.pdf", type: "file" }, { name: "cover.docx", type: "file" }, ], }, { name: "images", type: "folder", children: [ { name: "photo.jpg", type: "file" }, ], }, { name: "notes.txt", type: "file" }, ], }; // সব file-এর নাম বের করা: function getAllFiles(node, path = "") { const currentPath = path ? `${path}/${node.name}` : node.name; if (node.type === "file") { return [currentPath]; // Base Case } // Recursive Case — সব children-এ apply করো: return node.children.flatMap(child => getAllFiles(child, currentPath)); } console.log(getAllFiles(fileSystem)); // → ["root/documents/resume.pdf", "root/documents/cover.docx", // "root/images/photo.jpg", "root/notes.txt"] // Nested Object flatten করা: function flatten(obj, prefix = "") { return Object.entries(obj).reduce((acc, [key, value]) => { const newKey = prefix ? `${prefix}.${key}` : key; if (typeof value === "object" && value !== null && !Array.isArray(value)) { return { ...acc, ...flatten(value, newKey) }; // Recursive } return { ...acc, [newKey]: value }; // Base Case }, {}); } const nested = { a: { b: { c: 1 }, d: 2 }, e: 3 }; console.log(flatten(nested)); // → { "a.b.c": 1, "a.d": 2, "e": 3 }

Recursion বনাম Iteration এবং Tail Call Optimization

// ❌ Naive Fibonacci — Exponential Time (খুব ধীর): // fibonacci(50) হাজার বছর লাগবে! // ✅ Memoized Fibonacci: function fibMemo(n, memo = {}) { if (n in memo) return memo[n]; if (n <= 1) return n; memo[n]=fibMemo(n - 1, memo) + fibMemo(n - 2, memo); return memo[n]; } console.log(fibMemo(50)); // → 12586269025 ✅ (তাৎক্ষণিক) // Tail Recursion — Stack Overflow এড়ানো: // Tail Call=Recursive call-ই শেষ operation, অন্য কিছু নেই function factorialTail(n, acc=1) { if (n <=1) return acc; return factorialTail(n - 1, n * acc); // Tail Call ✅ } console.log(factorialTail(10)); // → 3628800 // Iteration (Loop) দিয়ে — সবচেয়ে নিরাপদ বড় সংখ্যায়: function factorialLoop(n) { let result=1; for (let i=2; i <=n; i++) result *=i; return result; } console.log(factorialLoop(10)); // → 3628800
Recursion কখন ব্যবহার করবে: Tree বা Graph traverse করতে, Nested data process করতে, Divide and Conquer algorithm-এ। সংখ্যার হিসাবে (factorial, fibonacci) Loop বেশি দক্ষ। Stack Overflow এড়াতে বড় input-এ Memoization বা Iteration ব্যবহার করো।

🔷 IIFE ও Special Function Patterns

IIFE — Immediately Invoked Function Expression IIFE

// গঠন: (function() { ... })(); // অথবা: (() => { ... })(); // ১. সাধারণ IIFE: (function() { const secret = "আমি IIFE-র ভেতরে"; console.log(secret); // → আমি IIFE-র ভেতরে })(); // console.log(secret); // → ReferenceError (বাইরে নেই) // ২. Arrow IIFE: (() => { console.log("Arrow IIFE চলছে"); })(); // ৩. IIFE-তে মান ফেরত: const config = (function() { const env = "production"; // private return { isProduction: env === "production", apiUrl: env === "production" ? "https://api.example.com" : "http://localhost:3000", }; })(); console.log(config.isProduction); // → true console.log(config.apiUrl); // → https://api.example.com // ৪. IIFE-তে Parameter: (function(global, $) { console.log("Library initializing..."); })(window, jQuery); // global scope pollution ছাড়া

Pure Functions — পার্শ্বপ্রতিক্রিয়াহীন Function Pure

// ✅ Pure Function — একই input = একই output, side effect নেই: function add(a, b) { return a + b; } function getFullName(first, last) { return `${first} ${last}`; } function double(arr) { return arr.map(x => x * 2); } // মূল array পরিবর্তন নেই // ❌ Impure Function — side effect আছে: let total = 0; function addToTotal(n) { total += n; // বাইরের state পরিবর্তন! return total; } // ❌ Impure — random বা date নির্ভর: function getRandomGreeting() { const greetings = ["হ্যালো", "নমস্কার", "হাই"]; return greetings[Math.floor(Math.random() * greetings.length)]; // প্রতিবার ভিন্ন output! } // Pure Function-এর সুবিধা: const prices = [100, 250, 80, 320]; // ❌ Impure — মূল array পরিবর্তন: function applyDiscountImpure(arr, pct) { for (let i = 0; i < arr.length; i++) arr[i] *=(1 - pct / 100); return arr; } // ✅ Pure — নতুন array ফেরত: function applyDiscount(arr, pct) { return arr.map(price=> price * (1 - pct / 100)); } const discounted = applyDiscount(prices, 10); console.log(prices); // → [100, 250, 80, 320] (অপরিবর্তিত ✅) console.log(discounted); // → [90, 225, 72, 288]

Currying — Multi-argument থেকে Single-argument chain Currying

// সাধারণ function: function add(a, b, c) { return a + b + c; } // Curried version: function curriedAdd(a) { return function(b) { return function(c) { return a + b + c; }; }; } console.log(curriedAdd(1)(2)(3)); // → 6 // Arrow দিয়ে সংক্ষিপ্ত: const curry = a => b => c => a + b + c; console.log(curry(1)(2)(3)); // → 6 // Practical Currying: const addTax = rate => price => price * (1 + rate / 100); const addVAT = addTax(15); const addGST = addTax(18); console.log(addVAT(1000)); // → 1150 console.log(addGST(1000)); // → 1180 // Generic curry function: function curryify(fn) { return function curried(...args) { if (args.length >= fn.length) { return fn(...args); } return function(...moreArgs) { return curried(...args, ...moreArgs); }; }; } const curriedMultiply = curryify((a, b, c) => a * b * c); console.log(curriedMultiply(2)(3)(4)); // → 24 console.log(curriedMultiply(2, 3)(4)); // → 24 console.log(curriedMultiply(2)(3, 4)); // → 24 console.log(curriedMultiply(2, 3, 4)); // → 24

🔷 Async Functions — Asynchronous Programming

Async Function হলো Asynchronous কোড লেখার সবচেয়ে পরিষ্কার পদ্ধতি। async keyword দিয়ে তৈরি এই function সবসময় Promise ফেরত দেয় এবং ভেতরে await ব্যবহার করা যায়।

async/await-এর গঠন ও ব্যবহার Syntax

// async function সবসময় Promise ফেরত দেয়: async function getNumber() { return 42; } console.log(getNumber()); // → Promise { 42 } getNumber().then(n => console.log(n)); // → 42 // await — Promise resolve হওয়া পর্যন্ত অপেক্ষা: function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function countdown() { console.log("শুরু!"); await delay(1000); // ১ সেকেন্ড অপেক্ষা console.log("এক সেকেন্ড পার হলো"); await delay(1000); console.log("আরেক সেকেন্ড পার হলো"); } countdown(); // API Call: async function fetchUser(id) { const response = await fetch(`/api/users/${id}`); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } const user = await response.json(); return user; } // Error Handling: async function safeLoadUser(id) { try { const user = await fetchUser(id); console.log("ব্যবহারকারী:", user.name); return user; } catch (error) { console.log("Error:", error.message); return null; } }

Sequential বনাম Parallel Execution Performance

// ❌ Sequential — একটির পর একটি (মোট সময় বেশি): async function loadSequential() { const user = await fetchUser(1); // ১ সেকেন্ড অপেক্ষা const posts = await fetchPosts(1); // আরও ১ সেকেন্ড (মোট ২ সে.) const comments = await fetchComments(1); // আরও ১ সেকেন্ড (মোট ৩ সে.) return { user, posts, comments }; } // ✅ Parallel — একসাথে (মোট সময় সর্বোচ্চটার সমান): async function loadParallel() { const [user, posts, comments] = await Promise.all([ fetchUser(1), // তিনটি একসাথে শুরু fetchPosts(1), fetchComments(1), ]); // মোট সময় ≈ ১ সেকেন্ড (তিনটির মধ্যে সবচেয়ে বেশি) return { user, posts, comments }; } // Promise.allSettled — কিছু fail হলেও বাকি পাবে: async function loadAllSettled() { const results = await Promise.allSettled([ fetchUser(1), fetchUser(999), // এটা fail করবে fetchUser(2), ]); results.forEach((result, i) => { if (result.status === "fulfilled") { console.log(`User ${i}:`, result.value.name); } else { console.log(`User ${i} Error:`, result.reason.message); } }); } // Promise.race — প্রথম যে resolve করবে: async function withTimeout(promise, ms) { const timeout = new Promise((_, reject) => setTimeout(() => reject(new Error("Timeout!")), ms) ); return Promise.race([promise, timeout]); }

🔷 Built-in Functions — JavaScript-এর নিজস্ব Functions

Built-in Functions হলো JavaScript Engine-এ আগে থেকেই তৈরি করা function — আলাদাভাবে define করতে হয় না, সরাসরি ব্যবহার করা যায়। এগুলো Global Functions, এবং বিভিন্ন Object-এর Methods হিসেবে পাওয়া যায়।

Global Built-in Functions Global

Function কাজ উদাহরণ ফলাফল
parseInt(str, radix) String → পূর্ণসংখ্যা parseInt("42px", 10) 42
parseFloat(str) String → দশমিক সংখ্যা parseFloat("3.14abc") 3.14
isNaN(val) NaN কিনা (coercion সহ) isNaN("abc") true ⚠️
Number.isNaN(val) NaN কিনা (coercion ছাড়া) Number.isNaN("abc") false
isFinite(val) Finite সংখ্যা কিনা isFinite(Infinity) false
encodeURIComponent(str) URL-এ নিরাপদে encode encodeURIComponent("a b") "a%20b"
decodeURIComponent(str) Encoded URL decode decodeURIComponent("a%20b") "a b"
String(val) যেকোনো মান → String String(42) "42"
Number(val) যেকোনো মান → Number Number("42") 42
Boolean(val) যেকোনো মান → Boolean Boolean(0) false
// parseInt — radix সবসময় দাও: console.log(parseInt("42px", 10)); // → 42 (দশমিক) console.log(parseInt("0xff", 16)); // → 255 (হেক্সাডেসিমাল) console.log(parseInt("1010", 2)); // → 10 (বাইনারি) console.log(parseInt("abc", 10)); // → NaN (সংখ্যা দিয়ে শুরু নয়) console.log(parseInt("3.99", 10)); // → 3 (দশমিক কাটে) // parseFloat: console.log(parseFloat("3.14abc")); // → 3.14 console.log(parseFloat("abc")); // → NaN // isNaN vs Number.isNaN: console.log(isNaN("hello")); // → true ⚠️ (string convert করে) console.log(Number.isNaN("hello")); // → false ✅ (convert করে না) console.log(isNaN(NaN)); // → true console.log(Number.isNaN(NaN)); // → true ✅ // Type Conversion Functions: console.log(String(42)); // → "42" console.log(String(true)); // → "true" console.log(String(null)); // → "null" console.log(Number("3.14")); // → 3.14 console.log(Number("")); // → 0 console.log(Number(null)); // → 0 console.log(Number(undefined)); // → NaN console.log(Boolean(0)); // → false console.log(Boolean("")); // → false console.log(Boolean([])); // → true ⚠️ (খালি Array truthy!) // URL Encoding: const query = "নাম=করিম&শহর=ঢাকা"; const encoded = encodeURIComponent(query); console.log(encoded); // → "%E0%A6%A8%E0%A6%BE%E0%A6%AE%3D%E0%A6%95%E0%A6%B0%E0%A6%BF%E0%A6%AE..." console.log(decodeURIComponent(encoded)); // → নাম=করিম&শহর=ঢাকা

Math Object-এর Built-in Functions Math

// ===== সংখ্যা হিসাব ===== console.log(Math.abs(-15)); // → 15 (পরম মান) console.log(Math.pow(2, 10)); // → 1024 (ঘাত, ** operator-এর মতো) console.log(Math.sqrt(144)); // → 12 (বর্গমূল) console.log(Math.cbrt(27)); // → 3 (ঘনমূল) console.log(Math.log(Math.E)); // → 1 (প্রাকৃতিক লগ) console.log(Math.log2(8)); // → 3 (base-2 লগ) console.log(Math.log10(1000)); // → 3 (base-10 লগ) // ===== গোলাকার করা ===== console.log(Math.floor(4.9)); // → 4 (নিচে) console.log(Math.ceil(4.1)); // → 5 (উপরে) console.log(Math.round(4.5)); // → 5 (নিকটতম) console.log(Math.trunc(4.9)); // → 4 (দশমিক কাটে, চিহ্ন রাখে) console.log(Math.trunc(-4.9)); // → -4 (দশমিক কাটে) // ===== সর্বোচ্চ ও সর্বনিম্ন ===== console.log(Math.max(3, 7, 1, 9, 4)); // → 9 console.log(Math.min(3, 7, 1, 9, 4)); // → 1 console.log(Math.max(...[3, 7, 1])); // → 7 (Spread দিয়ে Array) // ===== Random ===== console.log(Math.random()); // → 0 থেকে 1-এর মধ্যে (1 বাদে) // Random Integer তৈরি: function randomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } console.log(randomInt(1, 6)); // → ১ থেকে ৬ (দাবার পাশা) console.log(randomInt(1, 100)); // → ১ থেকে ১০০ // ===== Trigonometry ===== console.log(Math.PI); // → 3.141592653589793 console.log(Math.sin(Math.PI / 2)); // → 1 console.log(Math.cos(0)); // → 1 console.log(Math.hypot(3, 4)); // → 5 (√(3²+4²)) // ===== অন্যান্য ===== console.log(Math.sign(-5)); // → -1 (ঋণাত্মক) console.log(Math.sign(0)); // → 0 console.log(Math.sign(5)); // → 1 (ধনাত্মক) console.log(Math.clamp); // → undefined (JS-এ নেই, নিজে তৈরি করো) // Clamp নিজে তৈরি: const clamp = (val, min, max) => Math.min(Math.max(val, min), max); console.log(clamp(150, 0, 100)); // → 100 console.log(clamp(-10, 0, 100)); // → 0 console.log(clamp(50, 0, 100)); // → 50

String-এর গুরুত্বপূর্ণ Built-in Methods String

const str = " আস-সালামু আলাইকুম বাংলাদেশ "; // ===== সন্ধান ও পরীক্ষা ===== console.log(str.includes("বাংলাদেশ")); // → true console.log(str.startsWith(" আস")); // → true console.log(str.endsWith("শ ")); // → true console.log(str.indexOf("আলাইকুম")); // → index নম্বর // ===== রূপান্তর ===== console.log(str.trim()); // → "আস-সালামু আলাইকুম বাংলাদেশ" console.log(str.trimStart()); // → শুরুর space সরায় console.log(str.trimEnd()); // → শেষের space সরায় console.log("hello".toUpperCase()); // → "HELLO" console.log("HELLO".toLowerCase()); // → "hello" // ===== ভাঙা ও জোড়া ===== const csv = "করিম,রাহেলা,সজল,নিলু"; const names = csv.split(","); console.log(names); // → ["করিম", "রাহেলা", "সজল", "নিলু"] console.log(names.join(" | ")); // → "করিম | রাহেলা | সজল | নিলু" // ===== কাটা ===== const text = "আস-সালামু আলাইকুম"; console.log(text.slice(0, 5)); // → "আস-সা" console.log(text.slice(-7)); // → "আলাইকুম" console.log(text.substring(4, 9)); // → "সালামু" (index 4-8) // ===== প্রতিস্থাপন ===== console.log("হ্যালো বিশ্ব".replace("বিশ্ব", "বাংলাদেশ")); // → "হ্যালো বাংলাদেশ" console.log("aabbcc".replaceAll("b", "x")); // → "aaxxcc" // ===== পুনরাবৃত্তি ও ভরাট ===== console.log("ক".repeat(5)); // → "ককককক" console.log("5".padStart(4, "0")); // → "0005" console.log("5".padEnd(4, "0")); // → "5000" // ===== অন্যান্য ===== console.log("হ্যালো".length); // → 6 (বাংলা character) console.log("hello".charAt(1)); // → "e" console.log("hello".charCodeAt(0)); // → 104 console.log(String.fromCharCode(65)); // → "A" console.log(" ".trim() === ""); // → true (blank check)

Array-এর গুরুত্বপূর্ণ Built-in Methods Array

const fruits = ["আম", "কলা", "লিচু", "পেয়ারা", "আনারস"]; // ===== খোঁজা ===== console.log(fruits.indexOf("লিচু")); // → 2 console.log(fruits.includes("আম")); // → true console.log(fruits.find(f => f.length > 3)); // → "লিচু" (প্রথম match) console.log(fruits.findIndex(f => f === "পেয়ারা")); // → 3 // ===== রূপান্তর ===== console.log(fruits.map(f => f + " ফল")); // → ["আম ফল", "কলা ফল", ...] console.log(fruits.filter(f => f.length <= 3)); // → ["আম"] (৩ character বা কম) console.log(fruits.reduce((acc, f)=> acc + f + ", ", "")); // → "আম, কলা, লিচু, পেয়ারা, আনারস, " // ===== পরিবর্তন ===== const arr = [1, 2, 3]; arr.push(4); // শেষে যোগ → [1,2,3,4] arr.unshift(0); // শুরুতে যোগ → [0,1,2,3,4] arr.pop(); // শেষ সরায় → [0,1,2,3] arr.shift(); // শুরু সরায় → [1,2,3] arr.splice(1, 1, 99); // index 1-এ 1টি সরিয়ে 99 রাখো → [1,99,3] // ===== কপি ও জোড়া ===== console.log([1,2,3].slice(1)); // → [2,3] console.log([1,2].concat([3,4])); // → [1,2,3,4] console.log([[1,2],[3,4]].flat()); // → [1,2,3,4] console.log([1,[2,[3]]].flat(Infinity)); // → [1,2,3] // ===== সাজানো ===== const nums = [10, 1, 21, 2]; console.log([...nums].sort()); // → [1, 10, 2, 21] ⚠️ String sort! console.log([...nums].sort((a,b) => a-b)); // → [1, 2, 10, 21] ✅ console.log([...nums].reverse()); // → [2, 21, 1, 10] // ===== Static Methods ===== console.log(Array.isArray([1,2])); // → true console.log(Array.from("hello")); // → ["h","e","l","l","o"] console.log(Array.from({length:5}, (_,i) => i+1)); // → [1,2,3,4,5] console.log(Array.of(1, 2, 3)); // → [1,2,3]

Number ও Object-এর Built-in Methods Number / Object

// ===== Number Methods ===== const n = 3.14159; console.log(n.toFixed(2)); // → "3.14" (দশমিক সংখ্যা নির্দিষ্ট) console.log(n.toPrecision(4)); // → "3.142" (মোট সংখ্যা নির্দিষ্ট) console.log((255).toString(16)); // → "ff" (hex) console.log((8).toString(2)); // → "1000" (binary) console.log(Number.isInteger(42)); // → true console.log(Number.isInteger(42.5)); // → false console.log(Number.isFinite(Infinity)); // → false console.log(Number.isFinite(42)); // → true console.log(Number.MAX_SAFE_INTEGER); // → 9007199254740991 console.log(Number.MIN_SAFE_INTEGER); // → -9007199254740991 console.log(Number.EPSILON); // → 2.220446049250313e-16 // ===== Object Static Methods ===== const user = { name: "করিম", age: 25, city: "ঢাকা" }; console.log(Object.keys(user)); // → ["name", "age", "city"] console.log(Object.values(user)); // → ["করিম", 25, "ঢাকা"] console.log(Object.entries(user)); // → [["name","করিম"], ["age",25], ...] // Object.assign — merge: const updated = Object.assign({}, user, { age: 26, email: "a@b.com" }); console.log(updated); // → { name: "করিম", age: 26, city: "ঢাকা", email: "a@b.com" } // Object.freeze — পরিবর্তন বন্ধ: const config = Object.freeze({ version: "1.0", debug: false }); config.version = "2.0"; // চুপচাপ ব্যর্থ console.log(config.version); // → "1.0" ✅ // Object.fromEntries — entries থেকে Object: const entries = [["a", 1], ["b", 2], ["c", 3]]; console.log(Object.fromEntries(entries)); // → { a: 1, b: 2, c: 3 } // Map → Object: const map = new Map([["x", 10], ["y", 20]]); console.log(Object.fromEntries(map)); // → { x: 10, y: 20 } // structuredClone — Deep Clone (আধুনিক): const original = { a: 1, nested: { b: 2 } }; const clone = structuredClone(original); clone.nested.b = 99; console.log(original.nested.b); // → 2 ✅ (অপরিবর্তিত)

Date ও JSON Built-in Functions Date / JSON

// ===== Date ===== const now = new Date(); console.log(now.getFullYear()); // → ২০২৫ (বর্তমান বছর) console.log(now.getMonth()); // → 0-11 (0 = জানুয়ারি) console.log(now.getDate()); // → মাসের দিন (1-31) console.log(now.getDay()); // → 0-6 (0 = রবিবার) console.log(now.getHours()); // → ঘণ্টা (0-23) console.log(now.getTime()); // → milliseconds since 1970 // Timestamp: console.log(Date.now()); // → current timestamp (ms) // Date তৈরি: const birthday = new Date("2000-01-15"); const specific = new Date(2025, 0, 15, 10, 30); // বছর, মাস(0=Jan), দিন, ঘণ্টা, মিনিট // Date Format: console.log(now.toLocaleDateString("bn-BD")); // → বাংলা তারিখ console.log(now.toISOString()); // → "2025-01-15T10:30:00.000Z" console.log(now.toLocaleString("bn-BD", { year: "numeric", month: "long", day: "numeric" })); // ===== JSON ===== const data = { name: "করিম", age: 25, hobbies: ["পড়া", "কোডিং"] }; // Object → JSON String: const jsonStr = JSON.stringify(data); console.log(jsonStr); // → '{"name":"করিম","age":25,"hobbies":["পড়া","কোডিং"]}' // সুন্দর formatting: console.log(JSON.stringify(data, null, 2)); // JSON String → Object: const parsed = JSON.parse(jsonStr); console.log(parsed.name); // → করিম // Replacer দিয়ে ফিল্টার: const safe = JSON.stringify( { name: "করিম", password: "secret", age: 25 }, ["name", "age"] // শুধু এই দুটো ); console.log(safe); // → '{"name":"করিম","age":25}'
Built-in Function-এর গুরুত্বপূর্ণ নিয়ম:
isNaN()-এর বদলে Number.isNaN() ব্যবহার করো — type coercion নেই।
parseInt()-এ সবসময় radix (10) দাও — না দিলে octal parsing হতে পারে।
→ Array sort-এ sort((a,b) => a-b) দাও — নইলে String sort হয়।
Math.random() Cryptographically secure নয় — password-এ ব্যবহার করো না।

🔷 দ্রুত রেফারেন্স — JavaScript Functions সম্পূর্ণ

কোন ধরনের Function কখন ব্যবহার করবে? Decision Guide

পরিস্থিতি সেরা পছন্দ কারণ
Top-level utility function Function Declaration Hoisting সুবিধা, পরিষ্কার
Callback (map, filter, event) Arrow Function সংক্ষিপ্ত, this সমস্যা নেই
Object Method Method Shorthand this = object, পরিষ্কার syntax
Constructor / Class class keyword পরিষ্কার OOP, Arrow constructor নেই
Private state রাখা Closure বাইরে access নেই, encapsulation
Infinite/Lazy sequence Generator Function yield দিয়ে pause/resume
API/Network/Async কাজ Async Function await, Promise সহজে সামলানো
একবারই চালু, scope দূষণ নেই IIFE initialization, module pattern
Nested/Tree data process Recursion স্বাভাবিক সমাধান
Function pipeline তৈরি HOF + Currying Reusable, composable

Function Syntax এক নজরে Syntax Summary

ধরন Syntax this Hoisted
Declaration function f(x) { return x; } Dynamic ✅ হ্যাঁ
Expression const f = function(x) { return x; } Dynamic ❌ না
Arrow const f = x => x * 2 Lexical ❌ না
Method const obj = { f(x) { return x; } } Dynamic ❌ না
IIFE (function() { ... })() Dynamic — (তাৎক্ষণিক)
Generator function* f() { yield 1; } Dynamic ✅ হ্যাঁ
Async async function f() { await ...; } Dynamic ✅ হ্যাঁ
Async Arrow const f = async () => { await ...; } Lexical ❌ না

সাধারণ ভুল ও সমাধান Common Mistakes

ভুল সমস্যা সমাধান
Arrow Function-এ Object return: x => {a: 1} {} body হিসেবে নেয়, Object নয় x => ({a: 1})
Event Handler-এ Arrow Function ও this this = outer (element নয়) Regular Function ব্যবহার করো
Recursion-এ Base Case ভুলে যাওয়া Stack Overflow Base Case অবশ্যই দাও
var দিয়ে Loop-এ Closure সব closure একই i share করে let ব্যবহার করো
await ছাড়া async function call Promise Object পাবে, মান নয় await দাও বা .then() ব্যবহার করো
Async-এ try...catch না দেওয়া Unhandled Promise rejection try...catch বা .catch() অবশ্যই
Sequential await (দরকার নেই) অপ্রয়োজনীয় ধীর Promise.all() দিয়ে Parallel করো

🧠 নিজেকে যাচাই করো

1. Arrow function-এর বিশেষত্ব?

2. Default parameter কী?

3. Higher-order function কী?

✏️ Task — এখন তুমি করো

portfolio card render করার function বানাও। Arrow function ব্যবহার করো।

ধাপ 10🏗️ Real Project — Interactive Portfolio

Portfolio-এ reusable functions দিয়ে card render করো।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio-এর সব JS function reusable করো।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

🌐 JavaScript DOM APIs — সম্পূর্ণ নোট

এই সেকশনে JavaScript-এর DOM (Document Object Model) — Element নির্বাচন, তৈরি, পরিবর্তন, Event Handling, DOM Traversal, এবং আধুনিক DOM APIs — বাংলায় উদাহরণসহ বিস্তারিত আলোচনা করা হয়েছে।


🔷 DOM কী ও কীভাবে কাজ করে?

DOM (Document Object Model) হলো Browser-এর HTML Document-কে JavaScript-এ ব্যবহারযোগ্য Object Tree হিসেবে উপস্থাপন। Browser HTML parse করে এই Tree তৈরি করে — JavaScript এটি পড়তে, পরিবর্তন করতে এবং নতুন উপাদান যোগ করতে পারে।

সহজ উদাহরণ — একটি Button-এ Click করলে Text পরিবর্তন হয়, নতুন List Item যোগ হয়, অথবা একটি Modal খোলে — এসবই DOM API-র মাধ্যমে সম্ভব।

DOM-এর বিভাগ কাজ মূল Method/Property
Element Selection HTML Element খুঁজে বের করা querySelector, getElementById
Element Creation নতুন Element তৈরি ও যোগ করা createElement, append
Content Manipulation Text ও HTML পরিবর্তন textContent, innerHTML
Attribute Manipulation Attribute পড়া ও পরিবর্তন setAttribute, dataset
Style Manipulation CSS পরিবর্তন style, classList
Event Handling User interaction সামলানো addEventListener
DOM Traversal Parent, Child, Sibling navigate parentElement, children
DOM Manipulation Element সরানো, কপি, স্থানান্তর remove, cloneNode

DOM Tree-এর গঠন Structure

// HTML: // <div id="app"> // <h1 class="title">হ্যালো বাংলাদেশ</h1> // <p>একটি অনুচ্ছেদ</p> // </div> // DOM Tree: // document // └── html // ├── head // └── body // └── div#app // ├── h1.title // │ └── "হ্যালো বাংলাদেশ" (Text Node) // └── p // └── "একটি অনুচ্ছেদ" (Text Node) // document Object = DOM-এর entry point: console.log(document.title); // → Page-এর title console.log(document.URL); // → বর্তমান URL console.log(document.body); // → body element console.log(document.head); // → head element console.log(document.documentElement); // → html element

🔷 Element Selection — Element খুঁজে বের করা

DOM-এ কাজ করতে প্রথমে Element খুঁজে বের করতে হয়। querySelectorquerySelectorAll CSS Selector ব্যবহার করে — এগুলোই সবচেয়ে শক্তিশালী ও আধুনিক পদ্ধতি।

Selection Methods — তুলনা Methods

Method কী ফেরত দেয়? Live? ব্যবহার
querySelector(css) প্রথম মিলটি (Element বা null) ✅ সবচেয়ে বেশি ব্যবহৃত
querySelectorAll(css) সব মিল (NodeList) ✅ একাধিক element দরকার হলে
getElementById(id) একটি Element বা null ID দিয়ে খুঁজলে
getElementsByClassName(cls) HTMLCollection (Live) ✅ Live ⚠️ পুরানো পদ্ধতি
getElementsByTagName(tag) HTMLCollection (Live) ✅ Live ⚠️ পুরানো পদ্ধতি
// ===== querySelector — প্রথম মিল ===== const title = document.querySelector("h1"); // tag const btn = document.querySelector("#submit-btn"); // id const error = document.querySelector(".error-msg"); // class const navLink = document.querySelector("nav a"); // nested const checked = document.querySelector('input[type="checkbox"]:checked'); // attribute+pseudo // ===== querySelectorAll — সব মিল (NodeList) ===== const allBtns = document.querySelectorAll("button"); const navLinks = document.querySelectorAll("nav a"); const inputs = document.querySelectorAll("input, textarea"); // একাধিক selector // NodeList iterate করা: allBtns.forEach(btn => { btn.style.cursor = "pointer"; }); // Array-এ convert করে Array methods ব্যবহার: const btnArray = Array.from(allBtns); // অথবা: const btnArray = [...allBtns]; const enabledBtns = btnArray.filter(btn => !btn.disabled); // ===== getElementById — ID দিয়ে ===== const app = document.getElementById("app"); // "#" ছাড়া // ===== Scoped Selection — নির্দিষ্ট Element-এর ভেতরে খোঁজা ===== const form = document.querySelector("#login-form"); const inputs2 = form.querySelectorAll("input"); // শুধু form-এর ভেতরে const submit = form.querySelector("[type='submit']"); // ===== Null চেক অবশ্যই ===== const maybeNull = document.querySelector("#nonexistent"); if (maybeNull) { maybeNull.textContent = "পাওয়া গেছে"; } // অথবা Optional Chaining: document.querySelector("#nonexistent")?.classList.add("active");

Live Collection বনাম Static NodeList সাবধান

// Live Collection — DOM বদলালে collection-ও বদলায়: const liveList = document.getElementsByClassName("item"); // Live! console.log(liveList.length); // → 3 // নতুন element যোগ করলে liveList-ও বদলে যাবে: const newDiv = document.createElement("div"); newDiv.className = "item"; document.body.appendChild(newDiv); console.log(liveList.length); // → 4 ⚠️ (আপনা আপনি বেড়েছে!) // Static NodeList — DOM বদলালেও পরিবর্তন হয় না: const staticList = document.querySelectorAll(".item"); // Static console.log(staticList.length); // → 3 (নতুন element যোগ হলেও ৩-ই থাকবে)

🔷 Content ও Attribute Manipulation

textContent, innerHTML ও innerText Content

Property কী করে? HTML Parse? XSS ঝুঁকি?
textContent Text পড়া ও লেখা (HTML tag বাদ) ❌ Plain text ✅ নিরাপদ
innerHTML HTML সহ পড়া ও লেখা ✅ HTML parse করে ⚠️ User input-এ বিপদ
innerText Rendered text (CSS-সচেতন) ❌ Plain text ✅ নিরাপদ
outerHTML Element নিজেসহ HTML ✅ HTML parse করে ⚠️ সাবধান
// HTML: <div id="box"><strong>হ্যালো</strong> বাংলাদেশ</div> const box = document.querySelector("#box"); // textContent — HTML strip করে শুধু text: console.log(box.textContent); // → "হ্যালো বাংলাদেশ" (strong tag বাদ) // innerHTML — HTML সহ: console.log(box.innerHTML); // → "<strong>হ্যালো</strong> বাংলাদেশ" // ===== লেখা ===== // textContent — HTML escape করে (নিরাপদ): box.textContent = "XSS"; // String হিসেবে দেখাবে, execute হবে না // → Page-এ দেখাবে: <strong>XSS</strong> (literal text) // innerHTML — HTML execute করে (সাবধান): box.innerHTML = "বোল্ড টেক্সট"; // বোল্ড হয়ে দেখাবে ✅ // ⚠️ User input এভাবে দেবে না: // box.innerHTML = userInput; // XSS attack সম্ভব! // ✅ User input নিরাপদে দেখাতে: function safeSetHTML(element, userText) { element.textContent = userText; // HTML escape হয়ে যায় } // Template Literal দিয়ে নিরাপদ HTML: const name = "করিম"; const score = 92; box.innerHTML = ` <div class="student"> <h3>${name}</h3> <p>স্কোর: <strong>${score}</strong></p> </div> `;

Attribute Manipulation Attributes

// HTML: <img id="avatar" src="old.jpg" alt="ছবি" data-user-id="42"> const img = document.querySelector("#avatar"); // getAttribute — attribute-এর মান পড়া: console.log(img.getAttribute("src")); // → "old.jpg" console.log(img.getAttribute("alt")); // → "ছবি" // setAttribute — attribute সেট করা: img.setAttribute("src", "new.jpg"); img.setAttribute("alt", "নতুন ছবি"); img.setAttribute("loading", "lazy"); // নতুন attribute যোগ // removeAttribute — attribute সরানো: img.removeAttribute("loading"); // hasAttribute — আছে কিনা চেক: console.log(img.hasAttribute("src")); // → true console.log(img.hasAttribute("onclick")); // → false // Built-in properties (সরাসরি): const link = document.querySelector("a"); console.log(link.href); // → full URL console.log(link.id); // → element-এর id link.href = "https://bd.com"; // ===== dataset — data-* attributes ===== // HTML: <div data-user-id="42" data-user-name="করিম" data-is-admin="true"> const card = document.querySelector("[data-user-id]"); // পড়া — camelCase-এ convert হয়: console.log(card.dataset.userId); // → "42" (data-user-id → userId) console.log(card.dataset.userName); // → "করিম" (data-user-name → userName) console.log(card.dataset.isAdmin); // → "true" (string!) // সেট করা: card.dataset.lastLogin = "2025-01-15"; // → data-last-login="2025-01-15" // Delete: delete card.dataset.isAdmin; // সব data attribute iterate: for (const [key, value] of Object.entries(card.dataset)) { console.log(`${key}: ${value}`); }

🔷 Style ও Class Manipulation

classList — Class পরিচালনা classList

// HTML: <div id="card" class="card">...</div> const card = document.querySelector("#card"); // ===== classList Methods ===== // add — class যোগ: card.classList.add("active"); card.classList.add("highlighted", "featured"); // একাধিক // remove — class সরানো: card.classList.remove("highlighted"); card.classList.remove("a", "b", "c"); // একাধিক // toggle — থাকলে সরাও, না থাকলে যোগ করো: card.classList.toggle("dark-mode"); // dark-mode নেই → যোগ হবে card.classList.toggle("dark-mode"); // dark-mode আছে → সরবে // toggle-এ force parameter: card.classList.toggle("active", true); // সবসময় add card.classList.toggle("active", false); // সবসময় remove // contains — আছে কিনা: console.log(card.classList.contains("active")); // → true/false // replace — পুরানো class-এর জায়গায় নতুন: card.classList.replace("card", "panel"); // সব class দেখা: console.log(card.classList.value); // → "panel active" console.log([...card.classList]); // → ["panel", "active"] // ===== Practical: Theme Toggle ===== const themeBtn = document.querySelector("#theme-btn"); themeBtn.addEventListener("click", () => { document.body.classList.toggle("dark-theme"); themeBtn.textContent = document.body.classList.contains("dark-theme") ? "☀️ লাইট মোড" : "🌙 ডার্ক মোড"; });

Inline Style — element.style style

const box = document.querySelector("#box"); // ===== style property সেট করা (camelCase!) ===== box.style.backgroundColor = "lightblue"; // background-color box.style.fontSize = "18px"; // font-size box.style.marginTop = "20px"; // margin-top box.style.borderRadius = "8px"; box.style.display = "flex"; // একসাথে অনেক style — cssText: box.style.cssText = ` background-color: #3b82f6; color: white; padding: 16px; border-radius: 8px; `; // ⚠️ cssText = পুরানো inline style মুছে দেয়! // Style পড়া — শুধু inline style: console.log(box.style.backgroundColor); // → "lightblue" (inline হলে) console.log(box.style.color); // → "" (CSS file থেকে হলে পাবে না!) // Computed Style — সব CSS মিলিয়ে (CSS file + inline): const computed = window.getComputedStyle(box); console.log(computed.backgroundColor); // → "rgb(59, 130, 246)" console.log(computed.fontSize); // → "18px" console.log(computed.display); // → "block" (CSS থেকেও) // CSS Custom Properties (Variables): document.documentElement.style.setProperty("--primary-color", "#3b82f6"); const primaryColor = getComputedStyle(document.documentElement) .getPropertyValue("--primary-color"); console.log(primaryColor); // → "#3b82f6" // ✅ সর্বোত্তম পদ্ধতি: Inline Style-এর বদলে Class toggle করো: // box.style.display = "none"; ← এর বদলে: box.classList.add("hidden"); // CSS-এ: .hidden { display: none; }

🔷 Element তৈরি ও DOM Manipulation

Element তৈরি ও যোগ করা Create

// ===== createElement ===== const newDiv = document.createElement("div"); newDiv.className = "card"; newDiv.id = "user-card"; newDiv.textContent = "নতুন Card"; // যোগ করার পদ্ধতি: const container = document.querySelector("#container"); container.appendChild(newDiv); // শেষে যোগ (পুরানো) container.append(newDiv); // শেষে যোগ (আধুনিক, multiple ও string নেয়) container.prepend(newDiv); // শুরুতে যোগ container.before(newDiv); // container-এর আগে (sibling হিসেবে) container.after(newDiv); // container-এর পরে // append — একসাথে অনেক কিছু: const p = document.createElement("p"); p.textContent = "একটি অনুচ্ছেদ"; container.append(p, " কিছু text ", document.createElement("hr")); // ===== insertAdjacentHTML — দ্রুত HTML insert ===== // 'beforebegin' | 'afterbegin' | 'beforeend' | 'afterend' container.insertAdjacentHTML("beforeend", ` <div class="item"> <h3>আইটেম ১</h3> <p>বিবরণ</p> </div> `); // ⚠️ User input-এ ব্যবহার করো না (XSS) // insertAdjacentElement — Element insert: const newItem = document.createElement("li"); newItem.textContent = "নতুন আইটেম"; const list = document.querySelector("ul"); list.insertAdjacentElement("afterbegin", newItem); // প্রথমে

Element সরানো, প্রতিস্থাপন ও কপি Remove / Clone

// ===== remove — Element মুছে ফেলা ===== const oldCard = document.querySelector(".old-card"); oldCard.remove(); // নিজেকেই মুছে ফেলে // পুরানো পদ্ধতি (parent লাগত): // oldCard.parentNode.removeChild(oldCard); // ===== replaceWith — প্রতিস্থাপন ===== const old = document.querySelector("#old-element"); const newEl = document.createElement("div"); newEl.textContent = "নতুন Element"; old.replaceWith(newEl); // old-এর জায়গায় newEl // ===== cloneNode — কপি করা ===== const original = document.querySelector(".template-card"); // Shallow clone (child নয়): const shallowCopy = original.cloneNode(false); // Deep clone (child সহ): const deepCopy = original.cloneNode(true); deepCopy.id = "cloned-card"; // id পরিবর্তন (duplicate id এড়াতে) container.append(deepCopy);

DocumentFragment — Performance-এর জন্য Performance

// ❌ প্রতিটি element আলাদা insert — অনেক reflow: const ul = document.querySelector("ul"); ["করিম", "রাহেলা", "সজল", "নিলু", "আরিফ"].forEach(name => { const li = document.createElement("li"); li.textContent = name; ul.appendChild(li); // প্রতিটিতে DOM reflow! }); // ✅ DocumentFragment — একবার insert: const fragment = document.createDocumentFragment(); ["করিম", "রাহেলা", "সজল", "নিলু", "আরিফ"].forEach(name => { const li = document.createElement("li"); li.textContent = name; fragment.appendChild(li); // Fragment-এ রাখো (DOM reflow নেই) }); ul.appendChild(fragment); // শুধু একবার DOM-এ insert — একটি reflow // ✅ innerHTML দিয়েও দ্রুত (XSS ঝুঁকি নেই এমন data-এ): const students = ["করিম", "রাহেলা", "সজল"]; ul.innerHTML = students .map(name => `<li>${name}</li>`) .join("");

🔷 DOM Traversal — Tree Navigate করা

DOM Traversal হলো একটি Element থেকে তার Parent, Child, বা Sibling Element-এ navigate করা।

Traversal Properties Properties

Property কী দেয়? Text Node?
parentElement সরাসরি parent Element ❌ Element only
children সব direct child Elements (HTMLCollection) ❌ Element only
firstElementChild প্রথম child Element ❌ Element only
lastElementChild শেষ child Element ❌ Element only
nextElementSibling পরের sibling Element ❌ Element only
previousElementSibling আগের sibling Element ❌ Element only
childNodes সব child Node (Text সহ) ✅ Text Node সহ
closest(selector) নিজে বা উপরে প্রথম মিলিত ancestor ❌ Element only
// HTML: // <ul id="list"> // <li class="item">আম</li> // <li class="item active">কলা</li> // <li class="item">লিচু</li> // </ul> const activeItem = document.querySelector(".active"); // ===== Parent ===== console.log(activeItem.parentElement); // → <ul id="list"> console.log(activeItem.parentElement.id); // → "list" // ===== Siblings ===== console.log(activeItem.nextElementSibling); // → <li>লিচু</li> console.log(activeItem.previousElementSibling); // → <li>আম</li> // ===== Children ===== const list = document.querySelector("#list"); console.log(list.children); // → HTMLCollection [li, li, li] console.log(list.children.length); // → 3 console.log(list.firstElementChild); // → <li>আম</li> console.log(list.lastElementChild); // → <li>লিচু</li> // সব children iterate: [...list.children].forEach((item, i) => { console.log(`${i + 1}. ${item.textContent}`); }); // ===== closest — ancestor খোঁজা ===== // HTML: <table><tr><td><button class="delete-btn">মুছুন</button></td></tr></table> const deleteBtn = document.querySelector(".delete-btn"); // button থেকে উপরে tr খোঁজা: const row = deleteBtn.closest("tr"); // নিজে বা ancestor-এ প্রথম tr const table = deleteBtn.closest("table"); // নিজে বা ancestor-এ প্রথম table console.log(row); // → <tr> console.log(table); // → <table> // ===== matches — নির্দিষ্ট selector কিনা চেক ===== console.log(activeItem.matches(".active")); // → true console.log(activeItem.matches(".item.active")); // → true console.log(activeItem.matches("h1")); // → false

🔷 Event Handling — User Interaction সামলানো

addEventListener — Event যোগ করা addEventListener

// গঠন: element.addEventListener(event, handler, options) // ===== মৌলিক Event ===== const btn = document.querySelector("#my-btn"); btn.addEventListener("click", function(event) { console.log("Click হয়েছে!"); console.log(event.target); // → ক্লিক করা element console.log(event.type); // → "click" console.log(event.timeStamp); // → কখন হয়েছে }); // Arrow Function দিয়ে: btn.addEventListener("click", (e) => { e.target.textContent = "ক্লিক হয়েছে ✅"; }); // Named Function (পরে remove করতে পারবে): function handleClick(e) { console.log("Click:", e.target.id); } btn.addEventListener("click", handleClick); // ===== removeEventListener ===== btn.removeEventListener("click", handleClick); // Named function লাগবে // ⚠️ Anonymous Arrow Function remove করা যায় না!

গুরুত্বপূর্ণ Event Types Event Types

বিভাগ Events বিশেষ Properties
Mouse click dblclick mouseenter mouseleave mousemove contextmenu clientX/Y, button
Keyboard keydown keyup keypress key, code, ctrlKey, shiftKey
Form submit change input focus blur reset target.value
Window load DOMContentLoaded resize scroll beforeunload scrollY, innerWidth
Drag dragstart dragover drop dragend dataTransfer
Touch touchstart touchmove touchend touches, changedTouches
// ===== Keyboard Events ===== document.addEventListener("keydown", (e) => { console.log(e.key); // → "a", "Enter", "ArrowLeft" console.log(e.code); // → "KeyA", "Enter", "ArrowLeft" console.log(e.ctrlKey); // → true (Ctrl চাপা থাকলে) // Shortcut: if (e.ctrlKey && e.key === "s") { e.preventDefault(); // Browser-এর default Save বন্ধ saveDocument(); } if (e.key === "Escape") closeModal(); }); // ===== Form Events ===== const form = document.querySelector("#my-form"); const input = document.querySelector("#search-input"); // submit — form জমা দেওয়া: form.addEventListener("submit", (e) => { e.preventDefault(); // Page reload বন্ধ const data = new FormData(form); console.log(data.get("username")); console.log(data.get("email")); }); // input — টাইপ করার সাথে সাথে: input.addEventListener("input", (e) => { console.log(e.target.value); // প্রতিটি character-এ }); // change — শেষ হলে: input.addEventListener("change", (e) => { console.log("চূড়ান্ত মান:", e.target.value); }); // focus ও blur: input.addEventListener("focus", () => input.classList.add("focused")); input.addEventListener("blur", () => input.classList.remove("focused")); // ===== Window Events ===== window.addEventListener("DOMContentLoaded", () => { // HTML parse হয়েছে, JavaScript চালাতে পারবে console.log("DOM প্রস্তুত"); }); window.addEventListener("load", () => { // সব resource (image, css) load হয়েছে console.log("Page সম্পূর্ণ লোড"); }); window.addEventListener("scroll", () => { if (window.scrollY > 100) { document.querySelector(".back-to-top")?.classList.add("visible"); } });

Event Object — বিস্তারিত Event Object

// Event Object-এর গুরুত্বপূর্ণ properties ও methods: document.addEventListener("click", (event) => { // ===== Target Properties ===== event.target; // সরাসরি যেটায় click হয়েছে event.currentTarget; // addEventListener যেখানে দেওয়া event.type; // → "click" // ===== Mouse Position ===== event.clientX; // viewport-এর relative X event.clientY; // viewport-এর relative Y event.pageX; // page-এর relative X event.pageY; // page-এর relative Y // ===== Modifier Keys ===== event.ctrlKey; // Ctrl চাপা? event.shiftKey; // Shift চাপা? event.altKey; // Alt চাপা? event.metaKey; // Cmd/Windows চাপা? // ===== Methods ===== event.preventDefault(); // Default action বন্ধ (link navigate, form submit) event.stopPropagation(); // Bubbling বন্ধ (parent-এ যাবে না) event.stopImmediatePropagation(); // অন্য handler-ও চলবে না });

🔷 Event Bubbling, Capturing ও Event Delegation

Event Bubbling ও Capturing Propagation

// Bubbling — নিচ থেকে উপরে (default): // HTML: <div id="outer"><div id="inner">Click</div></div> document.querySelector("#inner").addEventListener("click", () => { console.log("Inner clicked"); // ১ম }); document.querySelector("#outer").addEventListener("click", () => { console.log("Outer clicked"); // ২য় (bubble করে এসেছে) }); document.body.addEventListener("click", () => { console.log("Body clicked"); // ৩য় }); // Inner-এ click করলে: Inner → Outer → Body (উপরে bubble) // ===== stopPropagation — Bubble বন্ধ করা ===== document.querySelector("#inner").addEventListener("click", (e) => { e.stopPropagation(); // parent-এ bubble যাবে না console.log("শুধু Inner চলবে"); }); // ===== Capturing — উপর থেকে নিচে ===== document.querySelector("#outer").addEventListener("click", () => { console.log("Outer capture"); // Capturing phase-এ আগে চলে }, { capture: true }); // তৃতীয় parameter: true = capturing // Phase order: // Capturing: document → html → body → outer → inner // Bubbling: inner → outer → body → html → document

Event Delegation — Dynamic Elements-এ সেরা পদ্ধতি Delegation

// ❌ প্রতিটি button-এ আলাদা listener (খারাপ): document.querySelectorAll(".action-btn").forEach(btn => { btn.addEventListener("click", handleAction); // অনেক listener! }); // সমস্যা: পরে যোগ হওয়া button-এ কাজ করবে না! // ✅ Event Delegation — parent-এ একটি listener: document.querySelector("#btn-container").addEventListener("click", (e) => { const btn = e.target.closest("[data-action]"); // click হওয়া button খোঁজো if (!btn) return; // button নয় এমন click ignore const action = btn.dataset.action; switch (action) { case "delete": deleteItem(btn.dataset.id); break; case "edit": editItem(btn.dataset.id); break; case "share": shareItem(btn.dataset.id); break; } }); // Dynamic list — Delegation দিয়ে: const todoList = document.querySelector("#todo-list"); // Parent-এ একবার listener: todoList.addEventListener("click", (e) => { if (e.target.matches(".delete-btn")) { e.target.closest("li").remove(); // li সরিয়ে দাও } if (e.target.matches(".complete-btn")) { e.target.closest("li").classList.toggle("done"); } }); // পরে যোগ হওয়া item-ও কাজ করবে ✅: function addTodoItem(text) { todoList.insertAdjacentHTML("beforeend", ` <li> ${text} <button class="complete-btn">✓</button> <button class="delete-btn">✕</button> </li> `); }

addEventListener Options — once, passive, capture Options

// Options Object (তৃতীয় parameter): element.addEventListener("click", handler, { once: true, // শুধু একবার চলবে, তারপর auto-remove passive: true, // preventDefault() call করবে না — scroll performance উন্নত capture: false, // Capturing phase-এ চলবে কিনা (default: false = bubbling) }); // once — একবার মাত্র: btn.addEventListener("click", () => { console.log("শুধু প্রথমবার চলবে!"); }, { once: true }); // passive scroll — Performance উন্নত: window.addEventListener("scroll", () => { updateScrollIndicator(); }, { passive: true }); // scroll event-এ preventDefault নেই বলে browser optimize করতে পারে // Signal — AbortController দিয়ে multiple listener একসাথে বন্ধ: const controller = new AbortController(); const { signal } = controller; btn1.addEventListener("click", handler1, { signal }); btn2.addEventListener("mouseover", handler2, { signal }); form.addEventListener("submit", handler3, { signal }); // সব একসাথে বন্ধ: controller.abort(); // তিনটি listener-ই remove হবে

🔷 আধুনিক DOM APIs

Intersection Observer — Lazy Load ও Scroll Animation Intersection

// Intersection Observer — Element viewport-এ এলে callback: const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { // Element দৃশ্যমান হয়েছে: entry.target.classList.add("visible"); console.log(`${entry.target.id} দৃশ্যমান`); // একবার দেখার পর observe বন্ধ (Lazy Load-এ): observer.unobserve(entry.target); } }); }, { threshold: 0.1, // ১০% দৃশ্যমান হলে trigger rootMargin: "0px 0px -50px 0px", // নিচে ৫০px আগে trigger }); // সব .animate-on-scroll element observe করো: document.querySelectorAll(".animate-on-scroll").forEach(el => { observer.observe(el); }); // Lazy Image Loading: const imgObserver = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting) { const img = entry.target; img.src = img.dataset.src; // data-src → src imgObserver.unobserve(img); } }); }); document.querySelectorAll("img[data-src]").forEach(img => imgObserver.observe(img));

MutationObserver — DOM পরিবর্তন ট্র্যাক করা Mutation

// MutationObserver — DOM পরিবর্তন watch করা: const mutObserver = new MutationObserver((mutations) => { mutations.forEach(mutation => { if (mutation.type === "childList") { mutation.addedNodes.forEach(node => { if (node.nodeType === 1) { // Element node console.log("নতুন element যোগ:", node.tagName); } }); } if (mutation.type === "attributes") { console.log(`Attribute বদলেছে: ${mutation.attributeName}`); } }); }); mutObserver.observe(document.querySelector("#dynamic-area"), { childList: true, // child যোগ/সরানো watch subtree: true, // সব descendant attributes: true, // attribute পরিবর্তন characterData: true, // text পরিবর্তন }); // বন্ধ করা: mutObserver.disconnect();

ResizeObserver ও Web Animations API Resize / Animate

// ResizeObserver — Element-এর size পরিবর্তন watch: const resizeObserver = new ResizeObserver(entries => { entries.forEach(entry => { const { width, height } = entry.contentRect; console.log(`${entry.target.id}: ${Math.round(width)}×${Math.round(height)}`); // Responsive সিদ্ধান্ত: if (width < 400) { entry.target.classList.add("compact"); } else { entry.target.classList.remove("compact"); } }); }); resizeObserver.observe(document.querySelector("#resizable-panel")); //=====Web Animations API=====const box=document.querySelector("#animated-box"); const animation=box.animate([ { transform: "translateX(0)" , opacity: 1 }, { transform: "translateX(200px)" , opacity: 0.5 }, { transform: "translateX(0)" , opacity: 1 }, ], { duration: 1000, // মিলিসেকেন্ড iterations: Infinity, // অনন্তকাল চলবে easing: "ease-in-out" , fill: "forwards" , // শেষ অবস্থায় থাকবে }); // Control: animation.pause(); animation.play(); animation.cancel(); animation.playbackRate=2; // দ্বিগুণ গতি

🔷 দ্রুত রেফারেন্স — DOM APIs

কোন API কখন ব্যবহার করবে? Decision Guide

পরিস্থিতি সেরা পছন্দ কারণ
একটি Element খোঁজা querySelector(css) যেকোনো CSS Selector, সবচেয়ে নমনীয়
একাধিক Element খোঁজা querySelectorAll(css) Static NodeList, forEach কাজ করে
User input দেখানো textContent XSS নেই, HTML escape হয়
HTML insert করা insertAdjacentHTML innerHTML-এর চেয়ে নিরাপদ position control
Class যোগ/সরানো classList.toggle/add/remove পরিষ্কার, CSS-এ design রাখে
Event সামলানো addEventListener Multiple listener, remove করা যায়
Dynamic elements-এ event Event Delegation (parent-এ) Memory কম, নতুন element-এও কাজ করে
অনেক element যোগ করা DocumentFragment একবারেই DOM update — reflow কম
Scroll-এ animation IntersectionObserver scroll event-এর চেয়ে দক্ষ
Element size পরিবর্তন ResizeObserver resize event-এর চেয়ে সঠিক

সাধারণ ভুল ও সমাধান Common Mistakes

ভুল সমস্যা সমাধান
innerHTML = userInput XSS Attack সম্ভব textContent = userInput
querySelector-এ null check নেই TypeError: Cannot read properties of null el?.classList.add(...) বা if চেক
Anonymous Arrow-এ removeEventListener Remove করা যায় না Named function ব্যবহার করো
প্রতিটি dynamic element-এ listener Memory leak, নতুন element-এ কাজ করে না Event Delegation ব্যবহার করো
Loop-এ DOM insert (একটি একটি করে) প্রতিটিতে reflow — ধীর DocumentFragment বা innerHTML একবারে
element.style.color CSS file-এর value পড়া Inline style নেই হলে "" পাবে getComputedStyle(el).color

DOM API এক নজরে Quick Reference

বিভাগ Methods / Properties
Selection querySelector querySelectorAll getElementById closest matches
Content textContent innerHTML innerText outerHTML
Attribute getAttribute setAttribute removeAttribute hasAttribute dataset
Class/Style classList.add/remove/toggle/contains style getComputedStyle
Create/Insert createElement append prepend before after insertAdjacentHTML
Remove/Clone remove replaceWith cloneNode createDocumentFragment
Traversal parentElement children firstElementChild lastElementChild nextElementSibling previousElementSibling
Events addEventListener removeEventListener dispatchEvent
Observers IntersectionObserver MutationObserver ResizeObserver

🧠 নিজেকে যাচাই করো

1. getElementById() কী return করে?

2. innerHTML vs textContent?

3. addEventListener কী করে?

✏️ Task — এখন তুমি করো

button click করলে portfolio-এর section toggle হবে — DOM manipulation দিয়ে।

ধাপ 11🏗️ Real Project — Interactive Portfolio

DOM manipulation দিয়ে dynamic Portfolio বানাও।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio-এ smooth scroll navigation যোগ করো।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

🔒 JavaScript Strict Mode — সম্পূর্ণ নোট

এই সেকশনে JavaScript-এর Strict Mode — কী, কেন, কীভাবে চালু করতে হয়, কী কী বিধিনিষেধ আসে এবং Strict Mode-এ কোড কীভাবে নিরাপদ ও ভালো হয় — বাংলায় উদাহরণসহ বিস্তারিত আলোচনা করা হয়েছে।


🔷 Strict Mode কী ও কেন প্রয়োজন?

Strict Mode হলো JavaScript-এর একটি opt-in মোড যা কোডকে আরও কঠোর নিয়মে চালায়। এটি চালু থাকলে JavaScript Engine আরও বেশি Error ধরে, নিরাপদ নয় এমন কাজ করতে দেয় না এবং ভবিষ্যতের JavaScript-এর জন্য কিছু নাম reserve রাখে।

সহজ কথায় — Normal Mode-এ JavaScript অনেক ভুল চুপ করে এড়িয়ে যায়। Strict Mode-এ সেই ভুলগুলো সরাসরি Error throw করে

বিষয় Normal Mode Strict Mode
অঘোষিত variable ব্যবহার Global variable তৈরি হয় ⚠️ ReferenceError ✅
Read-only property-তে লেখা চুপচাপ ব্যর্থ ⚠️ TypeError ✅
with statement কাজ করে ⚠️ SyntaxError ✅
Duplicate parameter নাম কাজ করে ⚠️ SyntaxError ✅
Function-এ this (global) window/global object ⚠️ undefined ✅
Octal literal (0123) কাজ করে ⚠️ SyntaxError ✅
delete variable-এ চুপচাপ ব্যর্থ ⚠️ SyntaxError ✅
eval/arguments-এ নতুন binding কাজ করে ⚠️ SyntaxError ✅

🔷 Strict Mode চালু করার পদ্ধতি

"use strict" হলো একটি Directive — দেখতে String-এর মতো কিন্তু এটি JavaScript Engine-কে নির্দেশ দেয়। তিনটি স্তরে চালু করা যায়।

Global Strict Mode — পুরো File-এ Global

// ফাইলের একদম প্রথমে "use strict" দিতে হবে: "use strict"; // এখন পুরো ফাইলে Strict Mode চালু: x = 10; // → ReferenceError: x is not defined // কারণ: let/const/var ছাড়া variable declare করা যাবে না let validVar = 20; // ✅ সঠিক // ⚠️ "use strict" ফাইলের মাঝে দিলে কাজ করে না: let y = 5; "use strict"; // এটা শুধু একটি String Expression, Directive নয়! z = 10; // কাজ করবে (Strict Mode চালু হয়নি মাঝে দেওয়ায়)

Function-স্তরে Strict Mode Function

// পুরো ফাইল Non-strict: a = 5; // ⚠️ Global variable (Error নেই) function strictFunction() { "use strict"; // শুধু এই function-এ Strict Mode b = 10; // → ReferenceError ✅ } function normalFunction() { c = 15; // ⚠️ Global variable (Error নেই — এটা Non-strict) } strictFunction(); // → ReferenceError: b is not defined normalFunction(); // চলবে

ES Module — স্বয়ংক্রিয় Strict Mode ES Module

// myModule.mjs বা type="module" script: // কোনো "use strict" ছাড়াই Strict Mode স্বয়ংক্রিয়: export function greet(name) { // এখানে Strict Mode চালু undeclared = "test"; // → ReferenceError ✅ return `হ্যালো, ${name}!`; } // HTML-এ: // <script type="module" src="app.js"></script> // type="module" মানেই Strict Mode // Class-এ: class MyClass { // Class body সবসময় Strict Mode-এ: method() { undeclaredVar = 5; // → ReferenceError ✅ } } // কোথায় "use strict" লাগবে না: // ✅ ES Module (import/export আছে) // ✅ class body // ✅ Arrow function (outer Strict হলে) // কোথায় লাগবে: // → Traditional script tag (type="text/javascript") // → Node.js CommonJS module (.js with require/module.exports)
আধুনিক JavaScript-এ: সবসময় ES Module (type="module") বা class ব্যবহার করো — এগুলো automatically Strict Mode-এ চলে। Traditional script-এ সবসময় ফাইলের শুরুতে "use strict"; লেখো।

🔷 অঘোষিত Variable ও Global Pollution রোধ

Strict Mode-এর সবচেয়ে গুরুত্বপূর্ণ সুবিধা হলো অঘোষিত Variable ব্যবহার করতে দেয় না। Normal Mode-এ এটি চুপচাপ Global Variable তৈরি করে যা অনেক কঠিন Bug-এর কারণ।

অঘোষিত Variable — Normal vs Strict Variables

// ===== Normal Mode (সমস্যা) ===== function calculateTotal() { // typo: totaal (ভুল বানান): totaal = 100 + 200; // ⚠️ Global variable "totaal" তৈরি হয় return total; // undefined (total কখনো set হয়নি!) } function processOrder() { total = 0; // ⚠️ Global variable for (let i = 0; i < 5; i++) { total +=i; } } // ভয়ংকর বাগ: দুটো function একই "total" global share করে! calculateTotal(); // totaal (ভুল) Global তৈরি, total=undefined processOrder(); // total=10 //=====Strict Mode (নিরাপদ)====="use strict" ; function strictCalculate() { totaal=300; // → ReferenceError: totaal is not defined ✅ // এখনই ধরা পড়বে — production-এ যাবে না! } function strictProcess() { let total=0; // ✅ সঠিকভাবে declare করতে হবে for (let i=0; i < 5; i++) { total +=i; } return total; }

Global Pollution-এর বাস্তব উদাহরণ বিপদ

// ===== বড় প্রজেক্টে Global Pollution-এর বিপদ ===== // file1.js (Non-strict): function saveUser() { userName = "করিম"; // ⚠️ Global variable তৈরি! } // file2.js (Non-strict): function loadUser() { userName = "রাহেলা"; // ⚠️ একই Global variable override! } saveUser(); console.log(userName); // → "করিম" loadUser(); console.log(userName); // → "রাহেলা" ⚠️ (saveUser-এর data মুছে গেছে!) // ===== Strict Mode-এ ===== "use strict"; function saveUserStrict() { const userName = "করিম"; // ✅ Local, নিরাপদ } function loadUserStrict() { const userName = "রাহেলা"; // ✅ আলাদা Local, conflict নেই } // ===== Loop-এ সাধারণ টাইপো ===== // Normal Mode: for (i = 0; i < 5; i++) { // i Global হয়ে যায়! console.log(i); } console.log(i); // → 5 (Global leak!) // Strict Mode: "use strict" ; for (i=0; i < 5; i++) { // → ReferenceError: i is not defined // let i=... ব্যবহার করতে হবে }

🔷 this-এর আচরণ Strict Mode-এ

Strict Mode-এ this-এর আচরণ বদলে যায়। Normal Mode-এ standalone function call-এ this = window (browser) বা this = global (Node.js)। Strict Mode-এ এটি undefined হয় — অনেক accidental global access রোধ করে।

this — Normal বনাম Strict Mode this

// ===== Normal Mode ===== function showThis() { console.log(this); // → window (browser) / global (Node.js) } showThis(); // বিপদ — accidental global mutation: function updateCounter() { this.count++; // this = window, তাই window.count++ ! } updateCounter(); // Global state নষ্ট! // ===== Strict Mode ===== "use strict"; function showThisStrict() { console.log(this); // → undefined ✅ } showThisStrict(); function updateCounterStrict() { this.count++; // → TypeError: Cannot read properties of undefined ✅ // এখনই Error — Global state নষ্ট হওয়ার আগেই ধরা পড়বে } // Method call-এ this — উভয়ই একই: const obj = { name: "করিম", greet() { console.log(this.name); // → "করিম" (method call-এ this = obj) } }; obj.greet(); // ✅ উভয় মোডে একই // Method-কে detach করলে পার্থক্য: const greetFn = obj.greet; greetFn(); // Normal: window.name (undefined বা "") | Strict: TypeError ✅

call, apply, bind-এ Strict Mode call/apply/bind

// Normal Mode-এ call(null) বা call(undefined) → this = window: function logThis() { console.log(this); } logThis.call(null); // Normal: → window ⚠️ logThis.call(undefined); // Normal: → window ⚠️ // Strict Mode-এ call(null) → this = null (যা পাঠানো হয়েছে): "use strict"; function logThisStrict() { console.log(this); } logThisStrict.call(null); // Strict: → null ✅ logThisStrict.call(undefined); // Strict: → undefined ✅ logThisStrict.call(42); // Strict: → 42 logThisStrict.call("হ্যালো"); // Strict: → "হ্যালো" // Practical — এই পার্থক্য কেন গুরুত্বপূর্ণ: // Normal Mode-এ this=window হলে accidental global access সম্ভব। // Strict Mode-এ null বা undefined হলে সাথে সাথে Error — বাগ লুকায় না।

🔷 Read-only ও Non-configurable Property-তে লেখার নিয়ম

Normal Mode-এ Read-only Property-তে লিখলে JavaScript চুপচাপ ব্যর্থ হয় — কোনো Error নেই, মানও বদলায় না। এই Silent Failure-ই সবচেয়ে বিপজ্জনক bug তৈরি করে। Strict Mode-এ সঙ্গে সঙ্গে TypeError throw হয়।

Read-only Property ও Object.freeze() Read-only

// ===== Object.defineProperty — Read-only ===== const obj = {}; Object.defineProperty(obj, "id", { value: 42, writable: false, // লেখা যাবে না enumerable: true, configurable: false, // delete করা যাবে না }); // Normal Mode — চুপচাপ ব্যর্থ: obj.id = 100; // ⚠️ কিছুই হয় না console.log(obj.id); // → 42 (পরিবর্তন হয়নি, কিন্তু Error-ও নেই!) // Strict Mode — TypeError: "use strict"; obj.id = 100; // → TypeError: Cannot assign to read only property 'id' ✅ // ===== Object.freeze() ===== const config = Object.freeze({ version: "1.0", apiUrl: "https://api.example.com", maxRetries: 3, }); // Normal Mode: config.version = "2.0"; // ⚠️ চুপচাপ ব্যর্থ console.log(config.version); // → "1.0" (বদলায়নি, কিন্তু Error নেই!) // Strict Mode: "use strict"; config.version = "2.0"; // → TypeError ✅ // এখন জানা যাবে কোথায় config পরিবর্তনের চেষ্টা হচ্ছে // ===== Getter-only Property ===== const circle = { _radius: 5, get area() { return Math.PI * this._radius ** 2; } // setter নেই — read-only }; // Normal Mode: circle.area = 100; // ⚠️ চুপচাপ ব্যর্থ // Strict Mode: "use strict"; circle.area = 100; // → TypeError: Cannot set property area of #<Object> ✅

Non-configurable Property delete করা delete

// Non-configurable property delete করা: const obj = {}; Object.defineProperty(obj, "permanent", { value: "আমি স্থায়ী", configurable: false, // delete করা যাবে না }); // Normal Mode: delete obj.permanent; // → false (ব্যর্থ, কিন্তু Error নেই!) console.log(obj.permanent); // → "আমি স্থায়ী" // Strict Mode: "use strict"; delete obj.permanent; // → TypeError: Cannot delete property 'permanent' ✅ // ===== Variable ও Function delete নিষিদ্ধ ===== "use strict"; let myVar = 10; delete myVar; // → SyntaxError: Delete of an unqualified identifier in strict mode ✅ function myFn() {} delete myFn; // → SyntaxError ✅ // Built-in property delete নিষিদ্ধ: delete Object.prototype; // Strict: TypeError ✅ | Normal: false ⚠️

🔷 Duplicate Parameters ও অন্যান্য Strict Mode বিধিনিষেধ

Duplicate Parameter নাম Parameters

// Normal Mode — Duplicate parameter: function badFunc(x, y, x) { // ⚠️ x দুবার! return x + y; // শেষের x = argument[2] } console.log(badFunc(1, 2, 3)); // → 5 (x=3, y=2 — কিন্তু কোড অস্পষ্ট!) // Strict Mode — SyntaxError: "use strict"; function strictFunc(a, b, a) { // → SyntaxError: Duplicate parameter name ✅ return a + b; } // Destructuring-এ একই সমস্যা: function bad({ name: x, age: x }) {} // Normal: শেষের x জেতে // Strict: SyntaxError ✅

with Statement — সম্পূর্ণ নিষিদ্ধ with — নিষিদ্ধ

// Normal Mode — with statement (বিভ্রান্তিকর): const user = { name: "করিম", age: 25, city: "ঢাকা" }; with (user) { console.log(name); // → "করিম" (user.name নাকি local name?) console.log(age); // → 25 (user.age নাকি অন্য কোনো age?) // ⚠️ Variable resolution ambiguous — debugging nightmare! } // Strict Mode: "use strict"; with (user) { // → SyntaxError: Strict mode code may not include a with statement ✅ console.log(name); } // ✅ বিকল্প — Destructuring: const { name, age, city } = user; console.log(name, age, city);

Octal Literal, eval ও Reserved Words অন্যান্য

// ===== Octal Literal — নিষিদ্ধ ===== // Normal Mode: const n = 0123; // → 83 (octal!) ⚠️ console.log(n); // → 83 (বেশিরভাগ মানুষ ভাবে 123) // Strict Mode: "use strict"; const m = 0123; // → SyntaxError: Octal literals are not allowed in strict mode ✅ // ✅ বিকল্প — Explicit prefix: const octal = 0o123; // → 83 (স্পষ্ট Octal) const hex = 0x7B; // → 123 (স্পষ্ট Hex) const binary = 0b1010; // → 10 (স্পষ্ট Binary) // ===== eval — নতুন variable বাইরে যায় না ===== // Normal Mode: eval("var evalVar = 42"); console.log(evalVar); // → 42 ⚠️ (eval থেকে বাইরে চলে এসেছে!) // Strict Mode: "use strict"; eval("var evalVarStrict = 42"); // console.log(evalVarStrict); // → ReferenceError ✅ // ===== Reserved Words — Future Keywords ===== "use strict"; // এই নামে variable declare করা যাবে না: // let implements = 1; // SyntaxError // let interface = 2; // SyntaxError // let package = 3; // SyntaxError // let private = 4; // SyntaxError // let protected = 5; // SyntaxError // let public = 6; // SyntaxError // let static = 7; // SyntaxError // let yield = 8; // SyntaxError (ES6-এ keyword হয়েছে) // let let = 9; // SyntaxError console.log("Reserved words Strict Mode-এ protect করা"); // ===== arguments object — পরিবর্তন ===== function normalFunc(x) { arguments[0] = 99; console.log(x); // Normal: → 99 (arguments ও x linked!) ⚠️ } "use strict"; function strictFn(x) { arguments[0] = 99; console.log(x); // Strict: → original value (linked নয়) ✅ } strictFn(42); // → 42 (arguments[0]=99 করলেও x বদলায় না)

🔷 Strict Mode ও Classes, Modules

Class — স্বয়ংক্রিয় Strict Mode Class

// Class body সবসময় Strict Mode — "use strict" লাগবে না: class BankAccount { #balance; // Private field constructor(owner, initialBalance) { this.owner = owner; this.#balance = initialBalance; } deposit(amount) { // এখানে Strict Mode চালু: undeclaredVar = 10; // → ReferenceError ✅ (ধরা পড়বে) this.#balance += amount; } get balance() { return this.#balance; } } const account = new BankAccount("করিম", 5000); account.deposit(1000); console.log(account.balance); // → 6000 // Class-এর method detach করলে this = undefined (Strict): const { deposit } = account; // deposit(500); // → TypeError: Cannot read properties of undefined // Strict Mode-এর কারণে এই বাগ সাথে সাথে ধরা পড়ে

ES Module — স্বয়ংক্রিয় Strict Mode Module

// utils.js (ES Module): // "use strict" ছাড়াই Strict Mode: export function calculateTax(price, rate) { if (typeof price !== "number") { throw new TypeError("price অবশ্যই Number হতে হবে"); } taxAmount = price * rate; // → ReferenceError ✅ (let/const ছাড়া) const tax = price * rate; return tax; } // app.js: import { calculateTax } from "./utils.js"; // ✅ সবসময় এই পদ্ধতি ব্যবহার করো: // <script type="module" src="app.js"></script> // type="module" = ES Module = Strict Mode // ===== Practical: Strict Mode দিয়ে Error ধরা ===== "use strict"; // ১. Typo ধরা: function calculateArea(widht, height) { // typo: widht return widht * height; // ⚠️ Normal: Global "widht", Strict: ReferenceError } // ২. Property পরিবর্তন রোধ: const PI = Object.freeze({ value: 3.14159 }); "use strict"; PI.value = 3; // → TypeError ✅ (frozen object পরিবর্তন করা যাবে না) // ৩. this-এর বাগ ধরা: class Timer { constructor() { this.seconds = 0; } start() { // Regular function-এ this = undefined (Strict Mode): setInterval(function() { this.seconds++; // → TypeError: Cannot read properties of undefined ✅ // এর বদলে Arrow Function ব্যবহার করো! }, 1000); // ✅ সঠিক: setInterval(() => { this.seconds++; // Arrow = Lexical this = Timer instance }, 1000); } }

🔷 Strict Mode কেন সবসময় ব্যবহার করবে?

Strict Mode-এর সুবিধা ও সীমাবদ্ধতা সুবিধা

সুবিধা ব্যাখ্যা
Bug আগে ধরা পড়ে Silent Failure-এর বদলে সাথে সাথে Error — debugging সহজ
Global Pollution বন্ধ Accidental global variable তৈরি করা যায় না
নিরাপদ this Standalone function-এ this = undefined — accidental global access নেই
Performance উন্নত Engine আরও ভালো optimize করতে পারে (with, eval-বিহীন)
Secure কোড with statement ও eval-এর বিপজ্জনক feature বন্ধ
Future-proof ভবিষ্যতের keyword protect থাকে
সীমাবদ্ধতা ব্যাখ্যা
পুরানো কোডে সমস্যা পুরানো Non-strict কোডে হঠাৎ চালু করলে Error হতে পারে
Third-party Library পুরানো library Strict Mode-এ কাজ না-ও করতে পারে
with ব্যবহার নেই কেউ with-এর উপর নির্ভরশীল হলে সমস্যা (তবে with ব্যবহারই ভুল)

Strict Mode বনাম Non-strict — বাস্তব তুলনা Comparison

// ===== বাস্তব প্রজেক্টে Strict Mode-এর মূল্য ===== // সমস্যা ১: Typo → Global Variable // Non-strict: function updatePrice(prodcut, price) { // typo: prodcut prodcut.price = price; // prodcut = undefined, Global "prodcut" তৈরি! return prodcut; } // এই বাগ খুঁজে পেতে ঘণ্টার পর ঘণ্টা লাগতে পারে! // Strict: "use strict"; function updatePriceStrict(product, price) { prodcut.price = price; // → ReferenceError: prodcut is not defined ✅ // সাথে সাথে ধরা পড়বে, line number সহ } // সমস্যা ২: Read-only Config পরিবর্তন const APP_CONFIG = Object.freeze({ MAX_RETRY: 3, TIMEOUT: 5000, API_URL: "https://api.example.com" }); // Non-strict: APP_CONFIG.MAX_RETRY = 10; // ⚠️ চুপচাপ ব্যর্থ, কিন্তু বাগ লুকিয়ে থাকে console.log(APP_CONFIG.MAX_RETRY); // → 3 (বদলায়নি, কিন্তু কোড ভুল ভাবছিল) // Strict: "use strict"; APP_CONFIG.MAX_RETRY = 10; // → TypeError ✅ সাথে সাথে ধরা! // সমস্যা ৩: Duplicate Parameter // Non-strict: function merge(obj, obj) { // ⚠️ শেষের obj-ই কার্যকর return obj; } // Strict: "use strict"; function mergeStrict(source, source) { // → SyntaxError ✅ return source; }

সঠিকভাবে Strict Mode ব্যবহার Best Practice

// ✅ সেরা পদ্ধতি ১ — ES Module ব্যবহার করো: // <script type="module" src="app.js"></script> // Automatically Strict Mode // ✅ সেরা পদ্ধতি ২ — প্রতিটি Traditional Script-এর শুরুতে: "use strict"; const app = { init() { this.loadData(); this.bindEvents(); }, loadData() { /* ... */ }, bindEvents() { /* ... */ }, }; app.init(); // ✅ সেরা পদ্ধতি ৩ — Function wrapper (পুরানো কোডে নতুন function Strict করতে): (function() { "use strict"; // এই IIFE-র ভেতরে সব Strict function newFeature() { // Strict Mode } })(); // ❌ এভাবে করো না — মাঝে "use strict": let x = 5; "use strict"; // কাজ করে না, শুধু String Expression y = 10; // Global variable তৈরি হয় (Strict চালু হয়নি)
সোনার নিয়ম: আজ থেকে সব নতুন JavaScript ফাইলে প্রথম লাইনে "use strict"; লেখো — অথবা type="module" ব্যবহার করো। Strict Mode-এ Error হওয়া মানে বাগ সঠিক সময়ে ধরা পড়েছে। ESLint-এ "strict": "error" rule চালু রাখো।

🔷 দ্রুত রেফারেন্স — JavaScript Strict Mode

Strict Mode-এর সব নিয়ম এক নজরে Rules

নিয়ম Normal Mode Strict Mode
অঘোষিত variable Global variable তৈরি ⚠️ ReferenceError ✅
Read-only property লেখা Silent failure ⚠️ TypeError ✅
Non-configurable delete Silent failure (false) ⚠️ TypeError ✅
Duplicate parameter কাজ করে ⚠️ SyntaxError ✅
Octal literal (0123) 83 ⚠️ SyntaxError ✅
with statement কাজ করে ⚠️ SyntaxError ✅
Standalone function this window/global ⚠️ undefined ✅
call(null)-এ this window/global ⚠️ null ✅
eval-এ নতুন variable বাইরে দৃশ্যমান ⚠️ eval-এর ভেতরে সীমাবদ্ধ ✅
Variable delete Silent failure ⚠️ SyntaxError ✅
Reserved words (let, yield ইত্যাদি) variable নামে ব্যবহার করা যায় ⚠️ SyntaxError ✅
arguments ও parameter linking arguments[0] বদলালে parameter বদলায় ⚠️ Linked নয় ✅

কোথায় Strict Mode স্বয়ংক্রিয়? Auto Strict

Context Strict Mode? "use strict" লাগবে?
type="module" script ✅ সবসময় ❌ লাগবে না
class body ✅ সবসময় ❌ লাগবে না
ES Module (import/export) ✅ সবসময় ❌ লাগবে না
Traditional <script> tag ❌ Default Non-strict ✅ লিখতে হবে
Node.js CommonJS (.js) ❌ Default Non-strict ✅ লিখতে হবে
Node.js ESM (.mjs) ✅ সবসময় ❌ লাগবে না

সাধারণ ভুল ও সমাধান Common Mistakes

ভুল সমস্যা সমাধান
File-এর মাঝে "use strict" কাজ করে না — String Expression হিসেবে নেয় একদম প্রথম লাইনে দাও
Strict ও Non-strict file concatenate Strict file-এর directive হারিয়ে যেতে পারে সব file-এ "use strict" দাও বা ES Module ব্যবহার করো
Strict Mode-এ this ব্যবহার ভুল Standalone function-এ this = undefined → TypeError Arrow Function বা bind() ব্যবহার করো
Octal escape (\123) String-এ Octal escape Strict-এ নিষিদ্ধ \u0053 (Unicode) বা \x53 (Hex) ব্যবহার করো

🧠 নিজেকে যাচাই করো

1. 'use strict' কী করে?

2. Strict mode-এ undeclared variable?

3. Strict mode কোথায় লেখে?

✏️ Task — এখন তুমি করো

'use strict' যোগ করো। undeclared variable use করে error দেখো।

ধাপ 12🏗️ Real Project — Interactive Portfolio

Strict mode ব্যবহার করে safe JavaScript লেখো।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio-এর সব JS file-এ 'use strict' যোগ করো।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

🎯 JavaScript — Using (this) Keyword সম্পূর্ণ নোট

এই সেকশনে JavaScript-এর this keyword-এর সব দিক — In a Method, In a Function, Using it Alone, In Event Handlers, In Arrow Functions, Function Borrowing, এবং Explicit Binding (call/apply/bind) — বাংলায় উদাহরণসহ বিস্তারিত আলোচনা করা হয়েছে।


🔷 this কী ও কেন বিভ্রান্তিকর?

this হলো JavaScript-এর একটি বিশেষ keyword যা বর্তমান Execution Context-কে নির্দেশ করে। অন্য অনেক ভাষায় this সবসময় নির্দিষ্ট — কিন্তু JavaScript-এ this-এর মান নির্ধারিত হয় function কীভাবে call করা হয়েছে তার উপর, define করার সময় নয়।

একমাত্র ব্যতিক্রম — Arrow Function। Arrow Function-এ this define করার সময়ের context মনে রাখে (Lexical)।

Context this-এর মান Strict Mode-এ? উদাহরণ
Global Scope window (browser) / global (Node.js) একই Script-এর উপরে
Regular Function (standalone) window / global undefined fn()
Method Call যে Object-এ method আছে একই obj.method()
Arrow Function Lexical — বাইরের context একই () => {}
Constructor (new) নতুন তৈরি Object একই new Fn()
call() / apply() প্রথম argument-এ দেওয়া Object একই fn.call(obj)
bind() Permanently bind করা Object একই fn.bind(obj)
Event Handler Event-এর target element একই el.addEventListener
Class Method Class-এর Instance সবসময় Strict class Foo {}

this নির্ধারণের সহজ নিয়ম নিয়ম

// সহজ প্রশ্ন: "function-টি কীভাবে call হয়েছে?" // ১. new দিয়ে? → this = নতুন Object const obj = new MyClass(); // this = নতুন instance // ২. call/apply/bind দিয়ে? → this = প্রথম argument fn.call(myObj); // this = myObj // ৩. Object-এর method হিসেবে? → this = সেই Object obj.greet(); // this = obj // ৪. Arrow Function? → this = Lexical (বাইরের this) const arrow = () => this; // this = যেখানে define করা হয়েছে সেখানের this // ৫. উপরের কোনোটি নয়? → this = global (বা Strict-এ undefined) fn(); // this = window / undefined (Strict)

🔷 this — In a Function ও Using it Alone

Using it Alone — Global Scope-এ this Using it Alone

// Browser-এ একা this ব্যবহার (Using it Alone): console.log(this); // → Window object console.log(this === window); // → true // Global variable ও this: var globalVar = "আমি global"; console.log(this.globalVar); // → "আমি global" (var global-এ থাকে) // let/const global-এ নেই: let notOnWindow = "আমি let"; console.log(this.notOnWindow); // → undefined (let window-এ নেই) // Node.js-এ একা this: console.log(this); // → {} (module-এর exports object) console.log(global); // → Node.js-এর global object console.log(this === global); // → false (module-এ this ≠ global)

In a Function — Regular Function-এ this In a Function

// ===== Non-strict Mode — In a Function ===== function showThis() { console.log(this); } showThis(); // → Window object ⚠️ (Browser-এ) // Function-এর ভেতর function: function outer() { console.log("outer this:", this); // → window function inner() { console.log("inner this:", this); // → window (নিজের this নেই, global-এ যায়) } inner(); } outer(); // ===== Strict Mode — In a Function ===== "use strict"; function showThisStrict() { console.log(this); // → undefined ✅ } showThisStrict(); // Strict-এ this.property access করলে TypeError: function badAccess() { "use strict"; return this.name; // → TypeError: Cannot read properties of undefined } // badAccess(); // → Error! // ===== Nested Function-এ this সমস্যা ===== const counter = { count: 0, start: function() { console.log("start-এ this:", this); // → counter object ✅ function tick() { this.count++; // ⚠️ this = window (না counter)! console.log("tick-এ this:", this); // → window } tick(); // standalone call → this = window } }; counter.start(); // count বাড়েনি — window.count বেড়েছে! বড় বাগ!

🔷 this — In a Method

Method Call-এ this হলো যে Object-এর মাধ্যমে method call করা হয়েছে। এটি JavaScript-এ this-এর সবচেয়ে স্বাভাবিক ব্যবহার।

this In a Method — মূল ব্যবহার In a Method

const student = { name: "রাহেলা", score: 92, city: "ঢাকা", // Method: introduce() { return `আমার নাম ${this.name}, আমি ${this.city}-তে থাকি।`; }, // Method-এ this দিয়ে অন্য property access: getGrade() { if (this.score >= 80) return "A+"; if (this.score >= 70) return "A"; return "B"; }, // Method-এ this দিয়ে নিজেকে modify: updateScore(newScore) { this.score = newScore; return this; // Method chaining-এর জন্য নিজেকে ফেরত }, }; console.log(student.introduce()); // → আমার নাম রাহেলা, আমি ঢাকা-তে থাকি। console.log(student.getGrade()); // → A+ // Method Chaining — this ফেরত দিলে: student.updateScore(95).updateScore(98); console.log(student.score); // → 98 // ===== Nested Object-এ this ===== const school = { name: "ঢাকা স্কুল", department: { name: "বিজ্ঞান", getFullName() { // this = department (কাছের Object) return `${this.name} বিভাগ`; // school.name পেতে হলে আলাদাভাবে access করতে হবে } } }; console.log(school.department.getFullName()); // → বিজ্ঞান বিভাগ

Method Detachment — this হারানো বিপদ

const user = { name: "করিম", greet() { return `হ্যালো, ${this.name}!`; } }; // ✅ Method হিসেবে call — this = user: console.log(user.greet()); // → হ্যালো, করিম! // ❌ Detach করলে this হারায়: const greetFn = user.greet; // Method বের করা — this হারাল! console.log(greetFn()); // → হ্যালো, undefined! ⚠️ (Non-strict) // Strict: → TypeError: Cannot read properties of undefined // ❌ Callback হিসেবে পাঠালেও একই সমস্যা: setTimeout(user.greet, 1000); // → হ্যালো, undefined! ⚠️ // ❌ Destructuring-এও: const { greet } = user; greet(); // → হ্যালো, undefined! ⚠️ // ===== সমাধান ===== // ১. bind() — Permanently bind করা: const boundGreet = user.greet.bind(user); boundGreet(); // → হ্যালো, করিম! ✅ setTimeout(user.greet.bind(user), 1000); // ✅ // ২. Arrow Function Wrapper: setTimeout(() => user.greet(), 1000); // ✅ (Lexical this — user) // ৩. Arrow Function as Method (Class Field): const user2 = { name: "রাহেলা", greet: function() { return `হ্যালো, ${this.name}!`; } }; const bound = user2.greet.bind(user2); console.log(bound()); // → হ্যালো, রাহেলা! ✅

🔷 this — In Arrow Functions

Arrow Function-এ নিজস্ব this নেই। এটি define করার সময়ের বাইরের scope-এর this ব্যবহার করে। call(), apply(), বা bind() দিয়েও Arrow Function-এর this বদলানো যায় না।

this In Arrow Functions — Lexical this In Arrow Functions

// ===== Regular Function — Dynamic this ===== const timer1 = { name: "Timer 1", seconds: 0, start() { console.log(this.name); // → "Timer 1" ✅ (method call) setInterval(function() { this.seconds++; // ⚠️ this = window (standalone call) console.log(this.name); // → undefined (window.name নেই) }, 1000); } }; // ===== Arrow Function — Lexical this ===== const timer2 = { name: "Timer 2", seconds: 0, start() { console.log(this.name); // → "Timer 2" ✅ setInterval(() => { // Arrow: this = start() method-এর this = timer2 this.seconds++; console.log(`${this.name}: ${this.seconds}`); // → "Timer 2: 1, 2, 3..." }, 1000); } }; timer2.start(); // ✅ কাজ করবে // ===== Arrow Function-এ call/bind কাজ করে না ===== const obj = { value: 42 }; const arrowFn = () => { console.log(this); // this = Global (যেখানে define হয়েছে) }; arrowFn.call(obj); // → Global (obj-এ bind হয়নি!) arrowFn.bind(obj)(); // → Global (bind কাজ করেনি!) arrowFn.apply(obj); // → Global

Lexical this-এর Practical ব্যবহার Practical

// ১. Object Method-এর ভেতরে Callback: const processor = { prefix: "প্রক্রিয়া", items: ["আম", "কলা", "লিচু"], processAll() { // Arrow — this = processor return this.items.map(item => { return `${this.prefix}: ${item}`; // ✅ this = processor }); }, // ❌ Regular Function — this হারাবে: processAllBad() { return this.items.map(function(item) { return `${this.prefix}: ${item}`; // ⚠️ this = window }); } }; console.log(processor.processAll()); // → ["প্রক্রিয়া: আম", "প্রক্রিয়া: কলা", "প্রক্রিয়া: লিচু"] // ২. Promise Chain-এ: const fetcher = { baseURL: "https://api.example.com", fetchUser(id) { return fetch(`${this.baseURL}/users/${id}`) .then(res => res.json()) // Arrow → this = fetcher .then(data => { console.log(`${this.baseURL}: ${data.name}`); // ✅ this = fetcher return data; }); } }; // ৩. forEach, filter, reduce-এ: const report = { title: "মাসিক প্রতিবেদন", scores: [85, 92, 78, 95, 67], getAbove80() { return this.scores.filter(s => s > 80); // Arrow ✅ }, getSummary() { const avg = this.scores.reduce((a, b) => a + b, 0) / this.scores.length; return `${this.title}: গড় ${avg.toFixed(1)}`; // Arrow ✅ } }; console.log(report.getAbove80()); // → [85, 92, 95] console.log(report.getSummary()); // → মাসিক প্রতিবেদন: গড় 83.4 // ৪. Arrow Function-এ this — কখন বিপদ: const badObj = { name: "বিপদ", // ❌ Object Literal-এ Arrow Method — this = Global! greet: () => { return `হ্যালো, ${this.name}`; // this = window, name = undefined } }; console.log(badObj.greet()); // → হ্যালো, undefined ⚠️

Arrow বনাম Regular — কখন কোনটা? Decision Guide

পরিস্থিতি ব্যবহার করো কারণ
Object Literal Method Regular Function this = object দরকার
Callback (map, filter, forEach) Arrow Function Outer this ব্যবহার করা দরকার
setTimeout / setInterval Callback Arrow Function Outer this maintain করতে
Event Handler (this = element দরকার) Regular Function Arrow-এ this = element নয়, outer
Class Method Regular Method (shorthand) this = instance দরকার
Class Method যা Callback হবে Arrow Class Field bind করতে হবে না
Constructor Regular Function বা Class Arrow Constructor নেই

🔷 Function Borrowing — অন্য Object-এর Method ধার নেওয়া

Function Borrowing হলো একটি Object-এর method অন্য Object ব্যবহার করার কৌশল। call() বা apply() দিয়ে this পরিবর্তন করে যেকোনো Object-এ যেকোনো function চালানো যায়। এতে একই method বারবার লিখতে হয় না।

Function Borrowing-এর মূল ধারণা Concept

// ===== সমস্যা — একই method বারবার লেখা ===== const student1 = { name: "করিম", score: 85, introduce() { return `আমি ${this.name}, আমার স্কোর ${this.score}`; } }; const student2 = { name: "রাহেলা", score: 92, introduce() { // ⚠️ একই function আবার লেখা হচ্ছে! return `আমি ${this.name}, আমার স্কোর ${this.score}`; } }; // ===== সমাধান — Function Borrowing ===== const student3 = { name: "সজল", score: 78 }; const student4 = { name: "নিলু", score: 91 }; // student1-এর method student3 ধার নিচ্ছে: console.log(student1.introduce.call(student3)); // → আমি সজল, আমার স্কোর 78 ✅ // student1-এর method student4 ধার নিচ্ছে: console.log(student1.introduce.call(student4)); // → আমি নিলু, আমার স্কোর 91 ✅ // মূল student1 অপরিবর্তিত: console.log(student1.introduce()); // → আমি করিম, আমার স্কোর 85 ✅

Built-in Method Borrowing — Array ও Object থেকে Built-in Borrow

// ===== Array Method — Array-like Object-এ ধার দেওয়া ===== function listArgs() { // arguments Array-like, কিন্তু Array নয় — forEach নেই! // Array-এর forEach ধার নিচ্ছে: Array.prototype.forEach.call(arguments, function(arg, i) { console.log(`${i}: ${arg}`); }); } listArgs("আম", "কলা", "লিচু"); // → 0: আম // → 1: কলা // → 2: লিচু // Array.prototype.slice ধার নিয়ে arguments → real Array: function toArray() { return Array.prototype.slice.call(arguments); } console.log(toArray(1, 2, 3)); // → [1, 2, 3] ✅ // ===== NodeList-এ Array method ধার ===== // const divs = document.querySelectorAll("div"); // NodeList // Array.prototype.map.call(divs, el => el.textContent); // ===== Object.prototype.toString ধার — Type চেক ===== function getType(value) { // Object.prototype.toString call করে যেকোনো value-এর exact type পাওয়া: return Object.prototype.toString.call(value); } console.log(getType([])); // → "[object Array]" console.log(getType(null)); // → "[object Null]" console.log(getType(undefined)); // → "[object Undefined]" console.log(getType(new Date())); // → "[object Date]" console.log(getType(/regex/)); // → "[object RegExp]" console.log(getType(42)); // → "[object Number]"

Practical Function Borrowing Practical

// ১. Shared Method — একটি function অনেক Object-এ: function introduce() { return `আমার নাম ${this.name}, আমি ${this.profession}।`; } const doctor = { name: "ডা. করিম", profession: "চিকিৎসক" }; const engineer = { name: "ইঞ্জি. রাহেলা", profession: "প্রকৌশলী" }; const teacher = { name: "সজল স্যার", profession: "শিক্ষক" }; // একই function তিনটি Object ধার নিচ্ছে: console.log(introduce.call(doctor)); // → আমার নাম ডা. করিম, আমি চিকিৎসক। console.log(introduce.call(engineer)); // → আমার নাম ইঞ্জি. রাহেলা, আমি প্রকৌশলী। console.log(introduce.call(teacher)); // → আমার নাম সজল স্যার, আমি শিক্ষক। // ২. Inheritance ছাড়া Parent-এর Method ধার: const Animal = { breathe() { return `${this.name} শ্বাস নিচ্ছে`; }, eat(food) { return `${this.name} ${food} খাচ্ছে`; } }; const cat = { name: "বিড়াল" }; const dog = { name: "কুকুর" }; // Animal-এর method ধার নেওয়া — extends বা class ছাড়াই: console.log(Animal.breathe.call(cat)); // → বিড়াল শ্বাস নিচ্ছে ✅ console.log(Animal.eat.call(dog, "মাংস")); // → কুকুর মাংস খাচ্ছে ✅ // ৩. hasOwnProperty ধার — Override থেকে সুরক্ষা: const obj = { hasOwnProperty: false }; // hasOwnProperty override! // obj.hasOwnProperty("name") → TypeError ⚠️ // Safe: Object.prototype থেকে ধার নেওয়া: console.log(Object.prototype.hasOwnProperty.call(obj, "hasOwnProperty")); // → true ✅
Function Borrowing কখন ব্যবহার করবে:
→ Array method-গুলো Array-like object (arguments, NodeList)-এ ব্যবহার করতে।
→ একই utility function অনেক object-এ share করতে (Inheritance ছাড়া)।
Object.prototype.toString.call() দিয়ে exact type চেক করতে।
→ ES6-এর পরে অনেক ক্ষেত্রে Spread ([...args]) বা Array.from() দিয়ে সহজ করা যায়।

🔷 Explicit Binding — call, apply, bind

Explicit Binding দিয়ে নিজে বলে দেওয়া যায় কোন Object-কে this হিসেবে ব্যবহার করতে হবে। তিনটি পদ্ধতি: call(), apply(), bind()

call, apply ও bind — তুলনা Comparison

Method Call হয় কখন? Arguments ফেরত দেয়
call() তাৎক্ষণিক আলাদা আলাদা: call(obj, a, b) Function-এর return মান
apply() তাৎক্ষণিক Array-এ: apply(obj, [a, b]) Function-এর return মান
bind() পরে (নতুন function) আলাদা আলাদা: bind(obj, a) Bound function (নতুন)

call() — তাৎক্ষণিক call, this নির্দিষ্ট করে call

// গঠন: fn.call(thisArg, arg1, arg2, ...) function introduce(greeting, punctuation) { return `${greeting}, আমি ${this.name}, ${this.city} থেকে${punctuation}`; } const person1 = { name: "করিম", city: "ঢাকা" }; const person2 = { name: "রাহেলা", city: "চট্টগ্রাম" }; // একই function, ভিন্ন this: console.log(introduce.call(person1, "আস-সালামু আলাইকুম", "।")); // → আস-সালামু আলাইকুম, আমি করিম, ঢাকা থেকে। console.log(introduce.call(person2, "হ্যালো", "!")); // → হ্যালো, আমি রাহেলা, চট্টগ্রাম থেকে! // ===== call-এর Practical ব্যবহার ===== // ১. Inheritance — Parent Constructor call করা: function Animal(name, sound) { this.name = name; this.sound = sound; } function Dog(name) { Animal.call(this, name, "ঘেউ"); // Parent constructor call this.type = "কুকুর"; } const rex = new Dog("রেক্স"); console.log(rex.name); // → রেক্স console.log(rex.sound); // → ঘেউ console.log(rex.type); // → কুকুর // ২. Array-like Object-এ Array method: function sumArgs() { // arguments Array-like, সরাসরি reduce নেই: return Array.prototype.reduce.call(arguments, (a, b) => a + b, 0); } console.log(sumArgs(1, 2, 3, 4, 5)); // → 15 // ৩. toString — Object থেকে Type চেক: function getType(value) { return Object.prototype.toString.call(value); } console.log(getType([])); // → "[object Array]" console.log(getType(null)); // → "[object Null]" console.log(getType(new Date())); // → "[object Date]"

apply() — Array argument দিয়ে call apply

// গঠন: fn.apply(thisArg, [arg1, arg2, ...]) // call-এর মতোই, শুধু argument Array-এ দেওয়া হয় function introduce(greeting, punctuation) { return `${greeting}, আমি ${this.name}${punctuation}`; } const person = { name: "সজল" }; // call: introduce.call(person, "হ্যালো", "!"); // apply — Array-এ argument: introduce.apply(person, ["হ্যালো", "!"]); // একই ফলাফল, শুধু argument দেওয়ার পদ্ধতি ভিন্ন // ===== apply-এর Classic ব্যবহার (আগে Spread ছিল না) ===== const numbers = [3, 1, 4, 1, 5, 9, 2, 6]; // ES6 আগে — apply দিয়ে Array → arguments: const max = Math.max.apply(null, numbers); // → 9 const min = Math.min.apply(null, numbers); // → 1 // ✅ ES6-এর পরে Spread দিয়ে সহজে: const maxNew = Math.max(...numbers); // → 9 (এখন এটাই ব্যবহার করো) // apply এখনো কাজে লাগে — Dynamic argument Array: function logMessages(format, ...messages) { messages.forEach(msg => console.log(`[${this.name}] ${format}: ${msg}`)); } const logger = { name: "AppLogger" }; const msgs = ["সার্ভার চালু", "Database সংযুক্ত", "Ready"]; logMessages.apply(logger, ["INFO", ...msgs]); // Array spread করে argument হিসেবে // → [AppLogger] INFO: সার্ভার চালু // → [AppLogger] INFO: Database সংযুক্ত // → [AppLogger] INFO: Ready

bind() — Permanently this বাঁধা নতুন Function bind

// গঠন: const boundFn = fn.bind(thisArg, arg1, arg2, ...) // নতুন function তৈরি করে — call করে না function greet(greeting, punctuation) { return `${greeting}, ${this.name}${punctuation}`; } const karim = { name: "করিম" }; const rahela = { name: "রাহেলা" }; // bind — নতুন function: const greetKarim = greet.bind(karim); const greetRahela = greet.bind(rahela); console.log(greetKarim("হ্যালো", "!")); // → হ্যালো, করিম! console.log(greetRahela("নমস্কার", "।")); // → নমস্কার, রাহেলা। // ===== bind-এর Practical ব্যবহার ===== // ১. Class Method-এ Event Listener: class Button { constructor(label) { this.label = label; this.clicks = 0; // bind না করলে event handler-এ this = button element this.handleClick = this.handleClick.bind(this); } handleClick() { this.clicks++; console.log(`${this.label} ক্লিক হয়েছে: ${this.clicks} বার`); } mount(element) { element.addEventListener("click", this.handleClick); // bind করা, তাই ✅ } } const btn = new Button("সাবমিট"); // btn.mount(document.querySelector("#btn")); // ২. Partial Application — কিছু argument আগেই দেওয়া: function multiply(a, b) { return a * b; } const double = multiply.bind(null, 2); // null = this (দরকার নেই), 2 = a const triple = multiply.bind(null, 3); console.log(double(5)); // → 10 (multiply(2, 5)) console.log(triple(5)); // → 15 (multiply(3, 5)) // ৩. setTimeout-এ bind: class Countdown { constructor(from) { this.count = from; } tick() { console.log(this.count--); if (this.count >= 0) { setTimeout(this.tick.bind(this), 1000); // ✅ } } } // ৪. bind-এর bound function আবার bind করা যায় না: function test() { return this.val; } const bound1 = test.bind({ val: 1 }); const bound2 = bound1.bind({ val: 2 }); // দ্বিতীয় bind কাজ করে না! console.log(bound2()); // → 1 (প্রথম bind-ই শেষ কথা)

🔷 Constructor ও Class-এ this

Constructor Function-এ this Constructor

// Constructor Function — new দিয়ে call: function Person(name, age) { // new দিলে this = নতুন Object {} this.name = name; this.age = age; this.introduce = function() { return `আমি ${this.name}, ${this.age} বছর বয়স।`; }; // implicitly: return this; } const karim = new Person("করিম", 25); const rahela = new Person("রাহেলা", 22); console.log(karim.introduce()); // → আমি করিম, 25 বছর বয়স। console.log(rahela.introduce()); // → আমি রাহেলা, 22 বছর বয়স। // new ছাড়া call করলে: "use strict"; // const bad = Person("করিম", 25); // → TypeError: this = undefined // ===== new-এর ধাপসমূহ ===== // ১. new Person("করিম", 25) call হলো // ২. {} তৈরি: const instance = Object.create(Person.prototype) // ৩. this = instance হলো // ৪. Constructor-এর body চলল: this.name = "করিম"... // ৫. return this — নতুন instance ফেরত // Constructor-এ Explicit Object return করলে: function SpecialPerson(name) { this.name = name; return { special: true }; // Object return করলে এটাই পাবে } const sp = new SpecialPerson("করিম"); console.log(sp.name); // → undefined (this নয়, explicit Object পেয়েছে) console.log(sp.special); // → true

Class-এ this — Instance, Method ও Arrow Field Class

class BankAccount { #balance; // Private field constructor(owner, initialBalance) { // this = নতুন Instance this.owner = owner; this.#balance = initialBalance; this.transactions = []; } // Regular Method — this = instance: deposit(amount) { if (amount <= 0) throw new Error("পরিমাণ ধনাত্মক হতে হবে"); this.#balance +=amount; this.transactions.push({ type: "deposit" , amount }); return this; // Method Chaining } withdraw(amount) { if (amount> this.#balance) throw new Error("পর্যাপ্ত ব্যালেন্স নেই"); this.#balance -= amount; this.transactions.push({ type: "withdraw", amount }); return this; // Method Chaining } get balance() { return this.#balance; } // Arrow Function Class Field — this permanently bound: printStatement = () => { // এই method detach করলেও this = instance ✅ console.log(`${this.owner}-এর ব্যালেন্স: ৳${this.#balance}`); this.transactions.forEach(t => { console.log(` ${t.type}: ৳${t.amount}`); }); }; } const account = new BankAccount("করিম", 5000); // Method Chaining — this ফেরত দেওয়ায়: account.deposit(1000).deposit(500).withdraw(200); console.log(account.balance); // → 6300 // Arrow Method Detach করা যায়: const { printStatement } = account; printStatement(); // ✅ this = account (bound!) // Regular method detach করলে this হারাত // Inheritance: class SavingsAccount extends BankAccount { constructor(owner, initialBalance, interestRate) { super(owner, initialBalance); // Parent-এর this সেট this.interestRate = interestRate; // নিজের property } addInterest() { const interest = this.balance * (this.interestRate / 100); this.deposit(interest); return this; } } const savings = new SavingsAccount("রাহেলা", 10000, 5); savings.addInterest(); console.log(savings.balance); // → 10500

🔷 this — In Event Handlers

Event Handler-এ this-এর আচরণ function-এর ধরনের উপর নির্ভর করে। Regular Function-এ this = element, Arrow Function-এ this = outer context

this In Event Handlers — Regular vs Arrow In Event Handlers

// ===== Regular Function — this = element ===== const btn = document.querySelector("#my-btn"); btn.addEventListener("click", function(event) { console.log(this); // → button element ✅ console.log(this === event.currentTarget); // → true this.textContent = "ক্লিক হয়েছে!"; // ✅ Element পরিবর্তন this.classList.add("clicked"); // ✅ }); // ===== Arrow Function — this = outer context ===== btn.addEventListener("click", (event) => { console.log(this); // → window (Arrow-এ this = outer = global) ⚠️ console.log(event.target); // ✅ target দিয়ে element পাওয়া যায় event.target.textContent = "ক্লিক হয়েছে!"; // ✅ target ব্যবহার করো }); // ===== Class-এ Event Handler ===== class Toggle { constructor(element) { this.element = element; this.isOn = false; this.label = "Toggle"; // ❌ bind না করলে this হারাবে: // this.element.addEventListener("click", this.handleClick); // ✅ bind করতে হবে: this.element.addEventListener("click", this.handleClick.bind(this)); } handleClick() { this.isOn = !this.isOn; this.element.textContent = `${this.label}: ${this.isOn ? "চালু" : "বন্ধ"}`; } } // ✅ বিকল্প — Arrow Class Field: class ToggleArrow { constructor(element) { this.element = element; this.isOn = false; this.element.addEventListener("click", this.handleClick); // bind লাগবে না! } // Arrow Field — this permanently bound to instance: handleClick = () => { this.isOn = !this.isOn; this.element.textContent = this.isOn ? "চালু" : "বন্ধ"; }; }

Event Delegation-এ this ও event.target Delegation

// Event Delegation-এ this ও event.target-এর পার্থক্য: const list = document.querySelector("#todo-list"); list.addEventListener("click", function(event) { console.log(this); // → ul#todo-list (listener যেখানে) console.log(event.target); // → যেটায় click হয়েছে (li, button ইত্যাদি) console.log(event.currentTarget); // → ul#todo-list (this-এর মতোই) // closest দিয়ে সঠিক element খোঁজা: const item = event.target.closest("li"); if (!item) return; if (event.target.matches(".delete-btn")) { item.remove(); } if (event.target.matches(".toggle-btn")) { item.classList.toggle("done"); } }); // Arrow Handler-এ event.target ব্যবহার করতে হয়: list.addEventListener("click", (event) => { // this = outer (Arrow), তাই event.target ব্যবহার করো: const btn = event.target.closest("button"); if (btn?.dataset.action === "delete") { btn.closest("li")?.remove(); } });

🔷 this-এর Common Pitfalls ও সমাধান

সব Common Pitfalls ও সমাধান Pitfalls

const user = { name: "করিম", friends: ["রাহেলা", "সজল", "নিলু"], // ===== Pitfall ১: Nested Function-এ this ===== greetFriendsBad() { this.friends.forEach(function(friend) { // ⚠️ Regular Function — this = window console.log(`${this.name} বলছে: হ্যালো ${friend}!`); // → undefined বলছে: হ্যালো রাহেলা! }); }, // ✅ সমাধান ১: Arrow Function: greetFriendsGood() { this.friends.forEach(friend => { console.log(`${this.name} বলছে: হ্যালো ${friend}!`); // → করিম বলছে: হ্যালো রাহেলা! }); }, // ✅ সমাধান ২: self/that Pattern (পুরানো পদ্ধতি): greetFriendsSelf() { const self = this; // this সংরক্ষণ this.friends.forEach(function(friend) { console.log(`${self.name} বলছে: হ্যালো ${friend}!`); }); }, // ✅ সমাধান ৩: forEach-এ thisArg: greetFriendsThisArg() { this.friends.forEach(function(friend) { console.log(`${this.name} বলছে: হ্যালো ${friend}!`); }, this); // দ্বিতীয় argument = this }, }; user.greetFriendsGood(); // → করিম বলছে: হ্যালো রাহেলা! // → করিম বলছে: হ্যালো সজল! // → করিম বলছে: হ্যালো নিলু!
// ===== Pitfall ২: setTimeout-এ this ===== class Clock { constructor() { this.time = 0; } // ❌ Regular Function: startBad() { setTimeout(function() { this.time++; // ⚠️ this = window console.log(this.time); // → NaN }, 1000); } // ✅ Arrow: startGood() { setTimeout(() => { this.time++; console.log(this.time); // ✅ → 1 }, 1000); } // ✅ bind: startBind() { setTimeout(function() { this.time++; console.log(this.time); // ✅ → 1 }.bind(this), 1000); } } // ===== Pitfall ৩: Promise Chain-এ this ===== class DataService { constructor() { this.data = []; this.url = "https://api.example.com"; } // ❌ Regular Function-এ this হারায়: fetchBad() { return fetch(this.url) .then(function(res) { return res.json(); }) .then(function(data) { this.data = data; // ⚠️ this = undefined (Strict) }); } // ✅ Arrow Function: fetchGood() { return fetch(this.url) .then(res => res.json()) .then(data => { this.data = data; // ✅ this = DataService instance }); } // ✅ async/await (সবচেয়ে পরিষ্কার): async fetchBest() { const res = await fetch(this.url); this.data = await res.json(); // ✅ this = instance } } // ===== Pitfall ৪: Object Literal-এ Arrow Method ===== const calculator = { value: 0, // ❌ Arrow Method — this = Global: addBad: (n) => { this.value += n; // this = window! return this; }, // ✅ Regular Method: addGood(n) { this.value += n; // ✅ this = calculator return this; }, }; calculator.addGood(5).addGood(3); console.log(calculator.value); // → 8 ✅

🔷 দ্রুত রেফারেন্স — Using (this) Keyword

this-এর মান — সব Context-এ Quick Reference

Call Pattern this (Non-strict) this (Strict) উদাহরণ
Global scope window window Script-এর উপরে
Standalone function call window undefined fn()
Method call Calling object Calling object obj.fn()
new call নতুন instance নতুন instance new Fn()
call(obj) obj obj fn.call(obj)
apply(obj) obj obj fn.apply(obj, [])
bind(obj)() obj obj fn.bind(obj)()
Arrow function Lexical (outer) Lexical (outer) () => {}
Regular event handler event.currentTarget event.currentTarget el.addEventListener("click", fn)
Arrow event handler Outer context Outer context el.addEventListener("click", () => {})
Class method Instance Instance (Auto Strict) class Foo { method() {} }

সাধারণ ভুল ও সমাধান Common Mistakes

ভুল সমস্যা সমাধান
const fn = obj.method; fn(); this হারায় — window বা undefined obj.method.bind(obj) বা Arrow wrapper
forEach-এ Regular Function Callback-এ this = window Arrow Function ব্যবহার করো
setTimeout-এ Regular Function this = window Arrow বা bind(this)
Object Literal-এ Arrow Method this = window (outer) Regular Method (shorthand)
Class Method-কে Callback হিসেবে this = undefined (Strict) Constructor-এ bind বা Arrow Field
Arrow-এ call/bind দিয়ে this বদলানো কাজ করে না — Lexical this fixed Regular Function ব্যবহার করো
Nested Function-এ this Inner function-এ this = window Arrow বা const self = this
Array-like object-এ Array method সরাসরি forEach/map নেই — TypeError Array.prototype.forEach.call(obj) — Function Borrowing

Roadmap.sh-এর সব Topic এক নজরে Topics Summary

Topic this-এর মান সেকশন
Using it Alone window (Non-strict) / window (Strict) অংশ ২
In a Function window (Non-strict) / undefined (Strict) অংশ ২
In a Method Calling Object অংশ ৩
In Arrow Functions Lexical — বাইরের this অংশ ৪
Function Borrowing call/apply দিয়ে নির্দিষ্ট Object অংশ ৫
Explicit Binding — call প্রথম argument-এর Object অংশ ৬
Explicit Binding — apply প্রথম argument-এর Object অংশ ৬
Explicit Binding — bind Permanently bound Object অংশ ৬
In Event Handlers (Regular) event.currentTarget (Element) অংশ ৮
In Event Handlers (Arrow) Outer Context (Element নয়) অংশ ৮

call, apply, bind — এক নজরে Explicit Binding

পদ্ধতি Syntax তাৎক্ষণিক? কখন ব্যবহার
call() fn.call(obj, a, b) ✅ হ্যাঁ এক্ষুনি call, argument কম হলে
apply() fn.apply(obj, [a, b]) ✅ হ্যাঁ এক্ষুনি call, argument Array-এ আছে
bind() const f = fn.bind(obj) ❌ পরে call Event Handler, Callback, Partial Application

🧠 নিজেকে যাচাই করো

1. this কী?

2. Arrow function-এ this?

3. Method-এ this কী?

✏️ Task — এখন তুমি করো

portfolio object বানাও যেখানে this দিয়ে নিজের property access করে।

ধাপ 13🏗️ Real Project — Interactive Portfolio

this keyword দিয়ে Portfolio object বানাও।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio object-এর সব method this ব্যবহার করে লেখো।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

⏳ Asynchronous JavaScript — সম্পূর্ণ নোট

এই সেকশনে JavaScript-এর Asynchronous Programming-এর সব দিক — Event Loop, setTimeout, setInterval, Callbacks, Callback Hell, Promises, এবং async/await — বাংলায় উদাহরণসহ বিস্তারিত আলোচনা করা হয়েছে।


🔷 Synchronous vs Asynchronous — মূল ধারণা

JavaScript Single-threaded — একসাথে মাত্র একটি কাজ করতে পারে। কিন্তু Asynchronous programming-এর মাধ্যমে দীর্ঘ কাজ (Network request, Timer, File read) background-এ পাঠিয়ে দিয়ে বাকি কোড চালিয়ে যাওয়া যায়।

বিষয় Synchronous Asynchronous
Execution একটার পর একটা, ক্রমানুসারে শুরু করে, শেষের অপেক্ষা না করে পরেরটায় যায়
Blocking ✅ Blocking — আগেরটা শেষ না হলে পরেরটা আটকে থাকে ❌ Non-blocking — পরেরটা চলতে থাকে
উদাহরণ Math calculation, Array loop fetch(), setTimeout(), File read
UI-তে প্রভাব ⚠️ Long task হলে UI freeze হয় ✅ UI responsive থাকে
// ===== Synchronous — আটকে থাকে ===== console.log("১ম"); // ধরো এটা ৫ সেকেন্ডের কাজ: for (let i = 0; i < 1e9; i++) {} // Blocking! UI freeze! console.log("২য়"); // ৫ সেকেন্ড পরে console.log("৩য়"); // আউটপুট ক্রম: ১ম → (৫ সেকেন্ড অপেক্ষা) → ২য় → ৩য় //=====Asynchronous — আটকে না রেখে=====console.log("শুরু"); setTimeout(()=> { console.log("৫ সেকেন্ড পরে"); // background-এ wait করছে }, 5000); console.log("শেষ"); // setTimeout-এর জন্য অপেক্ষা করে না! // আউটপুট: শুরু → শেষ → (৫ সেকেন্ড পরে) → ৫ সেকেন্ড পরে

🔷 Event Loop — JavaScript-এর হৃদয়

Event Loop হলো JavaScript-এর Asynchronous programming-এর মূল প্রক্রিয়া। এটি Call Stack, Web APIs, এবং Task Queues-কে সমন্বয় করে।

Event Loop-এর উপাদান Components

উপাদান কাজ উদাহরণ
Call Stack চলমান function-গুলো LIFO stack-এ রাখে সব synchronous code
Web APIs Browser/Node background-এ async কাজ করে setTimeout, fetch, addEventListener
Microtask Queue Promise callback, queueMicrotask — সর্বোচ্চ priority .then(), .catch(), await
Callback Queue (Macro) Timer callback, Event callback — কম priority setTimeout, setInterval, DOM events
Event Loop Call Stack খালি হলে Queue থেকে callback নেয় Microtask আগে, তারপর Macro

Event Loop কীভাবে কাজ করে How it works

// Event Loop-এর ধাপ বোঝা: console.log("১"); // Call Stack-এ → চলে → Stack থেকে বের setTimeout(() => { console.log("২ (setTimeout)"); // Web API-তে যায় → শেষে Callback Queue-এ }, 0); Promise.resolve().then(() => { console.log("৩ (Promise)"); // Microtask Queue-এ যায় }); console.log("৪"); // Call Stack-এ → চলে → Stack থেকে বের // আউটপুট: // → ১ // → ৪ // → ৩ (Promise) ← Microtask আগে! // → ২ (setTimeout) ← Macro task পরে // ব্যাখ্যা: // ১. "১" ও "৪" synchronous — সাথে সাথে চলে। // ২. setTimeout → 0ms হলেও Callback Queue-এ যায়। // ৩. Promise.then → Microtask Queue-এ যায়। // ৪. Call Stack খালি হলে Event Loop দেখে: // আগে Microtask Queue (Promise) সব শেষ করে। // তারপর Callback Queue (setTimeout) থেকে নেয়।

Microtask vs Macrotask — Priority Priority

// Microtask সবসময় Macrotask-এর আগে চলে: setTimeout(() => console.log("Macro 1"), 0); setTimeout(() => console.log("Macro 2"), 0); Promise.resolve().then(() => console.log("Micro 1")); Promise.resolve().then(() => console.log("Micro 2")); Promise.resolve().then(() => console.log("Micro 3")); console.log("Sync"); // আউটপুট: // → Sync // → Micro 1 // → Micro 2 // → Micro 3 // → Macro 1 // → Macro 2 // Nested Microtask — সব শেষ না হওয়া পর্যন্ত Macro চলে না: Promise.resolve() .then(() => { console.log("Micro A"); return Promise.resolve(); }) .then(() => console.log("Micro B")) // এটাও Macro-র আগে চলবে .then(() => console.log("Micro C")); setTimeout(() => console.log("Macro"), 0); // → Micro A → Micro B → Micro C → Macro // queueMicrotask — নিজে Microtask যোগ করা: queueMicrotask(() => console.log("Custom Microtask")); // Promise.resolve().then() এর মতোই
মনে রাখো: Event Loop-এর Priority ক্রম — Synchronous CodeMicrotask Queue (Promise, queueMicrotask) → Macrotask Queue (setTimeout, setInterval, DOM events)। setTimeout(fn, 0) মানে "এখনই নয়, পরের Macrotask চক্রে"।

🔷 setTimeout ও setInterval

setTimeout — দেরিতে একবার চালানো setTimeout

// গঠন: setTimeout(callback, delay, ...args) // delay = milliseconds (1000ms = 1 সেকেন্ড) // ১. সাধারণ setTimeout: setTimeout(() => { console.log("২ সেকেন্ড পরে চলছে"); }, 2000); // ২. argument পাঠানো: setTimeout((name, city) => { console.log(`${name} — ${city}`); }, 1000, "করিম", "ঢাকা"); // → করিম — ঢাকা (১ সেকেন্ড পরে) // ৩. clearTimeout — বাতিল করা: const timerId = setTimeout(() => { console.log("এটা কখনো চলবে না"); }, 5000); clearTimeout(timerId); // বাতিল ✅ // ৪. delay=0 — পরের Microtask cycle-এ: setTimeout(() => console.log("setTimeout 0"), 0); console.log("Synchronous"); // → Synchronous → setTimeout 0 // ৫. Nested setTimeout — Adaptive Timing: function poll() { fetchData().then(data => { process(data); setTimeout(poll, 1000); // প্রতিটি শেষে পরেরটা schedule করে }); } // setInterval-এর চেয়ে এটা ভালো — আগেরটা শেষ না হলে পরেরটা শুরু হয় না

setInterval — বারবার চালানো setInterval

// গঠন: setInterval(callback, interval, ...args) // ১. সাধারণ setInterval: let count = 0; const intervalId = setInterval(() => { count++; console.log(`${count} সেকেন্ড হয়েছে`); if (count >= 5) { clearInterval(intervalId); // ৫ সেকেন্ড পরে বন্ধ console.log("Timer বন্ধ হলো"); } }, 1000); // ২. Clock: function startClock() { const clockId = setInterval(() => { const now = new Date(); const time = now.toLocaleTimeString("bn-BD"); document.querySelector("#clock").textContent = time; }, 1000); return clockId; // বন্ধ করার জন্য রেখে দাও } // ৩. clearInterval — বন্ধ করা: const id = setInterval(() => console.log("চলছে..."), 500); setTimeout(() => { clearInterval(id); console.log("বন্ধ হলো"); }, 3000); // ⚠️ setInterval-এর সমস্যা: // callback চলতে interval-এর চেয়ে বেশি সময় লাগলে // callbacks স্তূপ হয়ে যায়। // ✅ সমাধান: Nested setTimeout ব্যবহার করো।

setTimeout বনাম setInterval — কখন কোনটা? Comparison

বিষয় setTimeout setInterval
চলে কতবার? একবার বারবার
Timing নির্দিষ্ট delay পরে প্রতিটি interval পরে
Overlap ঝুঁকি ❌ নেই (Nested হলে) ⚠️ আছে (callback দেরি হলে)
বন্ধ করা clearTimeout(id) clearInterval(id)
সেরা ব্যবহার একবার delayed action, Nested polling Simple repeating task (Clock)

🔷 Callbacks — Async-এর প্রথম সমাধান

Callback হলো এমন একটি function যা অন্য function-এ argument হিসেবে পাঠানো হয় এবং পরে call করা হয়। Async programming-এর প্রথম সমাধান ছিল Callback।

Callback-এর মূল ধারণা Concept

// Callback-এর সহজ উদাহরণ: function greet(name, callback) { console.log(`হ্যালো, ${name}!`); callback(); // callback call করা } greet("করিম", () => { console.log("Callback চলছে!"); }); // → হ্যালো, করিম! // → Callback চলছে! // Async Callback — setTimeout: function delayedGreet(name, callback) { setTimeout(() => { const message = `হ্যালো, ${name}!`; callback(message); // async কাজ শেষে callback }, 1000); } delayedGreet("রাহেলা", (msg) => { console.log(msg); // → হ্যালো, রাহেলা! (১ সেকেন্ড পরে) });

Error-first Callback Pattern — Node.js Style Error-first

// Error-first Callback — Node.js Convention: // গঠন: callback(error, data) // error = null হলে সফল, না হলে Error Object function readFile(filename, callback) { // File পড়ার simulation: setTimeout(() => { if (filename === "missing.txt") { callback(new Error("ফাইল পাওয়া যায়নি"), null); // Error } else { callback(null, "ফাইলের বিষয়বস্তু..."); // সফল } }, 1000); } // ব্যবহার — Error আগে চেক করো: readFile("data.txt", (error, data) => { if (error) { console.log("Error:", error.message); return; } console.log("ডেটা:", data); }); // Database query simulation: function getUser(id, callback) { setTimeout(() => { const users = { 1: { name: "করিম" }, 2: { name: "রাহেলা" } }; const user = users[id]; if (!user) { callback(new Error(`User ${id} পাওয়া যায়নি`), null); } else { callback(null, user); } }, 500); } getUser(1, (err, user) => { if (err) { console.log(err.message); return; } console.log(user.name); // → করিম });

🔷 Callback Hell — Pyramid of Doom

Callback Hell (বা "Pyramid of Doom") হলো যখন একাধিক async কাজ ক্রমানুসারে করতে হয় — প্রতিটি callback-এর ভেতরে আরেকটি callback, এভাবে নেস্টেড হতে থাকে এবং কোড পিরামিডের মতো দেখায়।

Callback Hell-এর উদাহরণ সমস্যা

// ক্রম: User লোড → তার Posts লোড → প্রথম Post-এর Comments লোড // ❌ Callback Hell: getUser(1, (err, user) => { if (err) { handleError(err); return; } console.log("User:", user.name); getPosts(user.id, (err, posts) => { if (err) { handleError(err); return; } console.log("Posts:", posts.length); getComments(posts[0].id, (err, comments) => { if (err) { handleError(err); return; } console.log("Comments:", comments.length); getLikes(comments[0].id, (err, likes) => { if (err) { handleError(err); return; } console.log("Likes:", likes.count); // আরও nested হতে থাকে... → // এটাই Callback Hell / Pyramid of Doom! }); }); }); }); // সমস্যাগুলো: // ১. ডানদিকে যেতে থাকে — পড়া কঠিন // ২. প্রতিটিতে আলাদা error handling // ৩. এক জায়গা থেকে বের হওয়া কঠিন // ৪. Test করা কঠিন

Callback Hell-এর আংশিক সমাধান — Named Functions সমাধান

// Named Function দিয়ে Flatten করা: function handleLikes(err, likes) { if (err) { handleError(err); return; } console.log("Likes:", likes.count); } function handleComments(err, comments) { if (err) { handleError(err); return; } console.log("Comments:", comments.length); getLikes(comments[0].id, handleLikes); } function handlePosts(err, posts) { if (err) { handleError(err); return; } console.log("Posts:", posts.length); getComments(posts[0].id, handleComments); } function handleUser(err, user) { if (err) { handleError(err); return; } console.log("User:", user.name); getPosts(user.id, handlePosts); } getUser(1, handleUser); // ✅ Flat, কিন্তু function ছড়িয়ে আছে // ✅ সবচেয়ে ভালো সমাধান: Promise ও async/await // (পরের অংশে বিস্তারিত)
⚠️ Callback Hell এড়াতে: আধুনিক JavaScript-এ Callback-এর বদলে সবসময় Promise বা async/await ব্যবহার করো। Callback শুধু Browser events ও কিছু Node.js API-তে দরকার হয়।

🔷 Promises — Callback Hell-এর সমাধান

Promise হলো async কাজের ভবিষ্যৎ ফলাফলের প্রতিশ্রুতি। তিনটি অবস্থায় থাকে — pending (অপেক্ষায়), fulfilled (সফল), rejected (ব্যর্থ)।

Promise তৈরি ও ব্যবহার Create & Use

// Promise তৈরি: const myPromise = new Promise((resolve, reject) => { // async কাজ: setTimeout(() => { const success = true; if (success) { resolve("সফল হয়েছে!"); // Fulfilled } else { reject(new Error("ব্যর্থ হয়েছে!")); // Rejected } }, 1000); }); // Promise ব্যবহার: myPromise .then(result => { console.log("সফল:", result); // → সফল: সফল হয়েছে! }) .catch(error => { console.log("Error:", error.message); }) .finally(() => { console.log("Promise শেষ"); // সবসময় চলে }); // ===== Promise-এ Callback Hell সমাধান ===== // Callback Hell ছিল: getUser(1, (err, user) => { getPosts(user.id, (err, posts) => { getComments(posts[0].id, (err, comments) => { /* ... */ }); }); }); // ✅ Promise Chain — সমতল, পড়তে সহজ: getUser(1) .then(user => { console.log("User:", user.name); return getPosts(user.id); // Promise ফেরত দাও }) .then(posts => { console.log("Posts:", posts.length); return getComments(posts[0].id); }) .then(comments => { console.log("Comments:", comments.length); }) .catch(error => { // যেকোনো জায়গার Error এখানে আসবে! console.log("Error:", error.message); }) .finally(() => { console.log("সব শেষ"); });

Promise-এর Static Methods Static Methods

// ===== Promise.all — সব সফল হলে ===== // সব Promise একসাথে চলে, সব সফল হলে array পাওয়া যায়। // একটিও fail হলে পুরোটা reject। Promise.all([ fetch("/api/users/1").then(r => r.json()), fetch("/api/posts").then(r => r.json()), fetch("/api/comments").then(r => r.json()), ]) .then(([user, posts, comments]) => { console.log(user.name, posts.length, comments.length); }) .catch(err => console.log("কোনো একটি fail:", err.message)); // ===== Promise.allSettled — সব শেষ হলে (fail হলেও) ===== Promise.allSettled([ Promise.resolve("সফল ১"), Promise.reject(new Error("ব্যর্থ")), Promise.resolve("সফল ২"), ]) .then(results => { results.forEach(result => { if (result.status === "fulfilled") { console.log("✅", result.value); } else { console.log("❌", result.reason.message); } }); }); // → ✅ সফল ১ // → ❌ ব্যর্থ // → ✅ সফল ২ // ===== Promise.race — প্রথমটাই গ্রহণ ===== const timeout = new Promise((_, reject) => setTimeout(() => reject(new Error("Timeout!")), 5000) ); Promise.race([ fetch("/api/data").then(r => r.json()), timeout, ]) .then(data => console.log("ডেটা এসেছে:", data)) .catch(err => console.log("Timeout বা Error:", err.message)); // ===== Promise.any — প্রথম সফলটাই গ্রহণ ===== Promise.any([ fetch("/api/server1").then(r => r.json()), fetch("/api/server2").then(r => r.json()), fetch("/api/server3").then(r => r.json()), ]) .then(data => console.log("প্রথম সফল সার্ভার:", data)) .catch(err => console.log("সব ব্যর্থ:", err.message)); // ===== Promise.resolve / Promise.reject ===== Promise.resolve(42).then(v => console.log(v)); // → 42 Promise.reject(new Error("Error")).catch(e => console.log(e.message));

Promise Chaining-এর সঠিক উপায় Chaining

// ❌ ভুল — Promise nest করা (Callback Hell-এর মতো): fetch("/api/user/1") .then(res => { res.json().then(user => { // Nested! ⚠️ fetch(`/api/posts/${user.id}`) .then(r => r.json()) .then(posts => console.log(posts)); }); }); // ✅ সঠিক — Promise return করে chain করো: fetch("/api/user/1") .then(res => res.json()) // Promise return .then(user => fetch(`/api/posts/${user.id}`)) // Promise return .then(res => res.json()) .then(posts => console.log(posts)) .catch(err => console.log(err.message)); // ❌ ভুল — .catch() শুধু শেষে না দিলে Error হারিয়ে যায়: somePromise .then(data => riskyOperation(data)) // Error এখানে হলে? .then(result => console.log(result)); // ⚠️ catch নেই! // ✅ সবসময় .catch() দাও: somePromise .then(data => riskyOperation(data)) .then(result => console.log(result)) .catch(err => console.log("Error:", err.message)); // ✅

🔷 async/await — Async কোডের সবচেয়ে পরিষ্কার রূপ

async/await হলো Promise-এর উপর তৈরি syntactic sugar যা Async code-কে Synchronous-এর মতো দেখায় — পড়তে সহজ, লিখতে সহজ।

async/await-এর গঠন ও মূল ব্যবহার Syntax

// async function: async function fetchUser(id) { // await = Promise resolve না হওয়া পর্যন্ত এখানে থামে const response = await fetch(`/api/users/${id}`); const user = await response.json(); return user; // Implicitly: return Promise.resolve(user) } // ব্যবহার: fetchUser(1).then(user => console.log(user.name)); // ===== Promise chain vs async/await ===== // Promise chain: function loadUserData(id) { return fetch(`/api/users/${id}`) .then(res => res.json()) .then(user => fetch(`/api/posts/${user.id}`)) .then(res => res.json()) .then(posts => ({ user, posts })) .catch(err => console.log(err.message)); } // ✅ async/await — অনেক পরিষ্কার: async function loadUserDataAsync(id) { const userRes = await fetch(`/api/users/${id}`); const user = await userRes.json(); const postsRes = await fetch(`/api/posts/${user.id}`); const posts = await postsRes.json(); return { user, posts }; } // Error Handling — try/catch: async function safeLoadUser(id) { try { const res = await fetch(`/api/users/${id}`); if (!res.ok) throw new Error(`HTTP Error: ${res.status}`); const user = await res.json(); console.log("ব্যবহারকারী:", user.name); return user; } catch (error) { console.log("Error:", error.message); return null; } finally { console.log("Request শেষ"); // সবসময় } }

Sequential vs Parallel — Await-এর পার্থক্য Performance

// ❌ Sequential await — একটার পর একটা (মোট সময় বেশি): async function loadSequential() { const user = await fetchUser(1); // ১ সেকেন্ড অপেক্ষা const posts = await fetchPosts(1); // + আরও ১ সেকেন্ড const profile = await fetchProfile(1); // + আরও ১ সেকেন্ড return { user, posts, profile }; // মোট ≈ ৩ সেকেন্ড } // ✅ Parallel await — Promise.all দিয়ে একসাথে: async function loadParallel() { const [user, posts, profile] = await Promise.all([ fetchUser(1), // তিনটি একসাথে শুরু fetchPosts(1), fetchProfile(1), ]); return { user, posts, profile }; // মোট ≈ ১ সেকেন্ড (সবচেয়ে বেশি সময়েরটা) } // ✅ কিছু Sequential, কিছু Parallel: async function loadMixed(userId) { // User আগে দরকার (posts-এর জন্য): const user = await fetchUser(userId); // User পেলে posts ও profile একসাথে: const [posts, profile] = await Promise.all([ fetchPosts(user.id), fetchProfile(user.id), ]); return { user, posts, profile }; }

Top-level await ও আধুনিক Pattern Modern

// Top-level await — ES Module-এ: // (type="module" script বা .mjs ফাইলে) const data = await fetch("/api/config").then(r => r.json()); console.log(data); // ✅ Module-এ সরাসরি await // ===== for await...of — Async Iteration ===== async function processStream(asyncIterable) { for await (const chunk of asyncIterable) { console.log("chunk:", chunk); } } // ===== await-এ Error Handling Pattern ===== // Tuple Pattern — [error, data]: async function safeAwait(promise) { try { const data = await promise; return [null, data]; } catch (error) { return [error, null]; } } // ব্যবহার: async function main() { const [err, user] = await safeAwait(fetchUser(1)); if (err) { console.log("Error:", err.message); return; } console.log("User:", user.name); } // ===== async IIFE — Top-level await ছাড়া ===== (async () => { const user = await fetchUser(1); console.log(user.name); })();

async/await বনাম Promise — কখন কোনটা? Comparison

বিষয় Promise Chain async/await
পড়তে সহজ? একাধিক .then()-এ কঠিন ✅ Synchronous-এর মতো
Error Handling .catch() try/catch — পরিচিত
Debugging Stack trace কঠিন ✅ সহজ, line number সঠিক
Parallel Promise.all() await Promise.all()
কোথায় ব্যবহার Simple chain, Utility function Complex async flow, তুলনামূলক ভালো

🔷 দ্রুত রেফারেন্স — Asynchronous JavaScript

কোন Async পদ্ধতি কখন ব্যবহার করবে? Decision Guide

পরিস্থিতি সেরা পছন্দ কারণ
নির্দিষ্ট সময় পরে একবার setTimeout Delayed single execution
বারবার নির্দিষ্ট সময়ে setInterval / Nested setTimeout Repeating tasks
Browser Event (click, scroll) Callback (addEventListener) DOM Events সবসময় Callback
একটি Async কাজ async/await পরিষ্কার, try/catch সহজ
একাধিক Async কাজ — সব দরকার Promise.all() সব সফল হলেই এগোবে, parallel
একাধিক — কিছু fail হলেও চলবে Promise.allSettled() সব result পাওয়া যায়
প্রথম সফলটা দরকার Promise.any() Fallback server ইত্যাদিতে
Timeout with fetch Promise.race() প্রথম যে resolve করবে
Async data stream for await...of Async Iterable iterate করতে

Async Programming-এর বিবর্তন Evolution

পদ্ধতি ES Version সুবিধা সমস্যা
Callback ES1 সহজ, DOM Events-এ দরকার Callback Hell, Error handling কঠিন
Promise ES6 Chain করা যায়, .catch() সহজ verbose, Nested হলে পড়া কঠিন
async/await ES2017 পরিষ্কার, try/catch, debug সহজ Sequential await হলে ধীর

সাধারণ ভুল ও সমাধান Common Mistakes

ভুল সমস্যা সমাধান
await ছাড়া async function call Promise object পাবে, মান নয় const data = await myFn()
Sequential await (দরকার নেই) অপ্রয়োজনীয় ধীর await Promise.all([...])
async-এ try/catch নেই Unhandled Promise rejection try/catch বা .catch() অবশ্যই
forEach-এ await forEach async-aware নয় for...of loop বা Promise.all
Promise-এ return ভুলে যাওয়া Chain ভেঙে যায় .then()-এ সবসময় return করো
setInterval-এ async callback Overlap হতে পারে Nested setTimeout ব্যবহার করো

🧠 নিজেকে যাচাই করো

1. async/await কী?

2. await কোথায় ব্যবহার করা যায়?

3. Promise.all() কী করে?

✏️ Task — এখন তুমি করো

fetch() দিয়ে https://jsonplaceholder.typicode.com/users থেকে data আনো।

ধাপ 14🏗️ Real Project — Interactive Portfolio

Portfolio-এ async/await দিয়ে data fetch করো।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio-এ GitHub API থেকে repository list দেখাও।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

🌍 Working with APIs — সম্পূর্ণ নোট

এই সেকশনে JavaScript-এ API-র সাথে কাজ করার সব পদ্ধতি — XMLHttpRequest, Fetch API, Headers, Request/Response, Error Handling, এবং Real-world Patterns — বাংলায় উদাহরণসহ বিস্তারিত আলোচনা করা হয়েছে।


🔷 API কী ও HTTP-এর মূল ধারণা

API (Application Programming Interface) হলো দুটো সফটওয়্যার যোগাযোগ করার নিয়মকানুন। Web-এ HTTP API দিয়ে Browser বা App Server-এর কাছ থেকে ডেটা নেয় বা পাঠায়।

HTTP Methods ও Status Codes HTTP

Method কাজ Body আছে? উদাহরণ
GET ডেটা আনা ❌ না ব্যবহারকারীর তালিকা দেখা
POST নতুন ডেটা তৈরি ✅ হ্যাঁ নতুন ব্যবহারকারী তৈরি
PUT পুরো রিসোর্স আপডেট ✅ হ্যাঁ পুরো profile বদলানো
PATCH আংশিক আপডেট ✅ হ্যাঁ শুধু নাম বদলানো
DELETE ডেটা মুছে ফেলা ❌ সাধারণত না ব্যবহারকারী মুছে ফেলা
Status Code অর্থ কখন আসে?
200 OK সফল GET, PUT, PATCH সফল হলে
201 Created তৈরি সফল POST সফল হলে
204 No Content সফল, কিন্তু body নেই DELETE সফল হলে
400 Bad Request ভুল request Invalid data পাঠালে
401 Unauthorized লগইন দরকার Token নেই বা expired
403 Forbidden অনুমতি নেই লগইন আছে কিন্তু permission নেই
404 Not Found পাওয়া যায়নি Resource নেই
500 Internal Server Error Server-এ সমস্যা Server crash বা bug

🔷 XMLHttpRequest — পুরানো পদ্ধতি

XMLHttpRequest (XHR) হলো Browser-এ HTTP request করার আদি পদ্ধতি। AJAX-এর মূল ভিত্তি। আধুনিক কোডে fetch() ব্যবহার করা উচিত, কিন্তু পুরানো codebase বোঝার জন্য XHR জানা দরকার।

XMLHttpRequest-এর মূল ব্যবহার Basic Usage

// XHR-এর ধাপসমূহ: // ১. Object তৈরি // ২. Request কনফিগার (open) // ৩. Event listener যোগ // ৪. Request পাঠানো (send) // ===== GET Request ===== const xhr = new XMLHttpRequest(); // open(method, url, async=true): xhr.open("GET", "https://jsonplaceholder.typicode.com/users/1", true); // Response type: xhr.responseType = "json"; // auto-parse JSON // readyState পরিবর্তনে: xhr.onreadystatechange = function() { // readyState: 0=UNSENT, 1=OPENED, 2=HEADERS, 3=LOADING, 4=DONE if (xhr.readyState === XMLHttpRequest.DONE) { if (xhr.status === 200) { console.log("ব্যবহারকারী:", xhr.response.name); } else { console.log("Error:", xhr.status); } } }; // আরও সহজ — onload ও onerror: xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300) { console.log("সফল:", xhr.response); } else { console.log("HTTP Error:", xhr.status); } }; xhr.onerror=function() { console.log("Network Error"); // DNS fail, timeout ইত্যাদি }; xhr.ontimeout=function() { console.log("Timeout হয়েছে"); }; xhr.timeout=5000; // ৫ সেকেন্ড timeout xhr.send(); // Request পাঠাও

XHR দিয়ে POST Request POST

// POST Request — নতুন ডেটা তৈরি: const xhrPost = new XMLHttpRequest(); xhrPost.open("POST", "https://jsonplaceholder.typicode.com/posts", true); // Header সেট করা: xhrPost.setRequestHeader("Content-Type", "application/json"); xhrPost.setRequestHeader("Authorization", "Bearer my-token"); xhrPost.onload = function() { if (xhrPost.status === 201) { const created = JSON.parse(xhrPost.responseText); console.log("তৈরি হয়েছে:", created.id); } }; // Body পাঠানো: const postData = JSON.stringify({ title: "আমার পোস্ট", body: "বিষয়বস্তু...", userId: 1, }); xhrPost.send(postData); // ===== XHR Progress — File Upload ===== const xhrUpload = new XMLHttpRequest(); xhrUpload.open("POST", "/api/upload"); xhrUpload.upload.onprogress = function(event) { if (event.lengthComputable) { const percent = Math.round((event.loaded / event.total) * 100); console.log(`আপলোড: ${percent}%`); } }; xhrUpload.onload = () => console.log("আপলোড সম্পন্ন"); const formData = new FormData(); formData.append("file", fileInput.files[0]); xhrUpload.send(formData);

XHR readyState ও Events readyState

readyState Constant অর্থ
0 UNSENT open() call হয়নি
1 OPENED open() call হয়েছে
2 HEADERS_RECEIVED Response header এসেছে
3 LOADING Response body আসছে
4 DONE সম্পন্ন
XHR কখন ব্যবহার করবে: File upload-এ Progress tracking (upload.onprogress), পুরানো Browser সাপোর্ট, পুরানো codebase। অন্য সব ক্ষেত্রে fetch() ব্যবহার করো।

🔷 Fetch API — আধুনিক HTTP Request

Fetch API হলো Browser-এ HTTP request করার আধুনিক ও সহজ পদ্ধতি। Promise-based হওয়ায় async/await দিয়ে পরিষ্কারভাবে লেখা যায়।

Fetch-এর মূল ব্যবহার — GET GET

// সবচেয়ে সহজ fetch: fetch("https://jsonplaceholder.typicode.com/users/1") .then(response => response.json()) .then(user => console.log(user.name)) .catch(error => console.log("Error:", error.message)); // ===== async/await দিয়ে (পরিষ্কার) ===== async function getUser(id) { try { const response = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`); // ⚠️ গুরুত্বপূর্ণ: 4xx, 5xx হলেও fetch reject করে না! if (!response.ok) { throw new Error(`HTTP Error: ${response.status} ${response.statusText}`); } const user = await response.json(); return user; } catch (error) { // Network error বা উপরের throw ধরবে: console.log("Error:", error.message); return null; } } const user = await getUser(1); console.log(user?.name); // → Leanne Graham // ===== Response-এর বিভিন্ন ধরন ===== const response = await fetch("/api/data"); // JSON (সবচেয়ে সাধারণ): const json = await response.json(); // Plain Text: const text = await response.text(); // Binary (Image, File): const blob = await response.blob(); // ArrayBuffer (Binary processing): const buffer = await response.arrayBuffer(); // FormData: const formData = await response.formData();

Fetch দিয়ে POST, PUT, PATCH, DELETE POST/PUT/DELETE

// ===== POST — নতুন তৈরি ===== async function createUser(userData) { const response = await fetch("https://jsonplaceholder.typicode.com/users", { method: "POST", headers: { "Content-Type": "application/json", "Authorization": "Bearer my-token", }, body: JSON.stringify(userData), }); if (!response.ok) throw new Error(`HTTP ${response.status}`); return await response.json(); } const newUser = await createUser({ name: "করিম", email: "karim@example.com", city: "ঢাকা", }); console.log("নতুন User ID:", newUser.id); // ===== PUT — পুরো আপডেট ===== async function updateUser(id, userData) { const response = await fetch(`/api/users/${id}`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(userData), }); if (!response.ok) throw new Error(`HTTP ${response.status}`); return await response.json(); } // ===== PATCH — আংশিক আপডেট ===== async function patchUser(id, changes) { const response = await fetch(`/api/users/${id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify(changes), // শুধু বদলানো fields }); if (!response.ok) throw new Error(`HTTP ${response.status}`); return await response.json(); } await patchUser(1, { name: "নতুন নাম" }); // শুধু name পাঠাচ্ছি // ===== DELETE ===== async function deleteUser(id) { const response = await fetch(`/api/users/${id}`, { method: "DELETE", }); if (!response.ok) throw new Error(`HTTP ${response.status}`); // 204 No Content — body নেই console.log(`User ${id} মুছে ফেলা হয়েছে`); } // ===== FormData পাঠানো ===== async function uploadFile(file) { const formData = new FormData(); formData.append("file", file); formData.append("description", "আমার ছবি"); const response = await fetch("/api/upload", { method: "POST", body: formData, // Content-Type দেবে না — browser নিজে multipart/form-data সেট করবে }); return await response.json(); }

Response Object — বিস্তারিত Response

const response = await fetch("/api/users/1"); // ===== Response Properties ===== console.log(response.ok); // → true (200-299 হলে) console.log(response.status); // → 200 console.log(response.statusText); // → "OK" console.log(response.url); // → full URL (redirect হলে final URL) console.log(response.redirected); // → true/false console.log(response.type); // → "basic", "cors", "opaque" console.log(response.headers); // → Headers object // ===== Response Headers ===== console.log(response.headers.get("Content-Type")); // → "application/json; charset=utf-8" console.log(response.headers.get("X-Total-Count")); // custom header response.headers.forEach((value, key) => { console.log(`${key}: ${value}`); }); // ⚠️ Body একবারই পড়া যায়: const text = await response.text(); // const json = await response.json(); // Error! Body already consumed! // Clone করে দুবার পড়া: const responseCopy = response.clone(); const data1 = await response.json(); const data2 = await responseCopy.json(); // ✅

🔷 Headers ও Request Object

Headers Object — তৈরি ও ব্যবহার Headers

// Headers Object তৈরি করার পদ্ধতি: // ১. Plain Object হিসেবে (সহজ): const headers1 = { "Content-Type": "application/json", "Authorization": "Bearer eyJhbGci...", "Accept": "application/json", "X-Custom-Header": "আমার Header", }; // ২. Headers Class দিয়ে (বেশি নমনীয়): const headers2 = new Headers(); headers2.append("Content-Type", "application/json"); headers2.append("Authorization", "Bearer my-token"); headers2.set("Accept", "application/json"); // set = override করে // পড়া: console.log(headers2.get("Content-Type")); // → "application/json" console.log(headers2.has("Authorization")); // → true // মুছে ফেলা: headers2.delete("X-Custom-Header"); // Iterate: for (const [key, value] of headers2) { console.log(`${key}: ${value}`); } // ৩. Object থেকে Headers: const headers3 = new Headers({ "Content-Type": "application/json", "Authorization": "Bearer token", }); // ===== সাধারণ Headers ===== // Content-Type: কী পাঠাচ্ছি // application/json — JSON data // multipart/form-data — File upload // application/x-www-form-urlencoded — Form data // Authorization: Authentication // Bearer — JWT // Basic — Username:Password // API-Key — API Key // Accept: কী ধরনের response চাই // application/json // text/html // Cache-Control: Caching নির্দেশনা // no-cache, no-store, max-age=3600

Request Object — Reusable Request Request

// Request Object তৈরি: const request = new Request("https://api.example.com/users", { method: "POST", headers: new Headers({ "Content-Type": "application/json", "Authorization": "Bearer token", }), body: JSON.stringify({ name: "করিম" }), mode: "cors", // "cors" | "no-cors" | "same-origin" credentials: "include", // "omit" | "same-origin" | "include" cache: "no-cache", // "default" | "no-cache" | "reload" | "force-cache" redirect: "follow", // "follow" | "error" | "manual" }); // Request Properties: console.log(request.url); // → "https://api.example.com/users" console.log(request.method); // → "POST" console.log(request.headers.get("Content-Type")); // → "application/json" // fetch-এ Request Object পাঠানো: const response = await fetch(request); // Clone করে একই request আবার: const clonedReq = request.clone(); const response2 = await fetch(clonedReq);

🔷 Error Handling ও Edge Cases

fetch()-এর সবচেয়ে বিভ্রান্তিকর দিক হলো — HTTP 4xx বা 5xx error আসলেও Promise reject হয় না। শুধু Network failure-এ reject হয়। তাই response.ok চেক করা অবশ্যই দরকার।

Fetch-এ সঠিক Error Handling Error Handling

// ❌ ভুল — HTTP error ধরা পড়বে না: async function badFetch(url) { try { const response = await fetch(url); const data = await response.json(); // 404-এও এখানে আসবে! return data; } catch (error) { // শুধু Network error ধরবে console.log("Network Error:", error.message); } } // ✅ সঠিক — HTTP error আলাদাভাবে চেক করো: async function goodFetch(url, options = {}) { try { const response = await fetch(url, options); if (!response.ok) { // HTTP error — body-তে error message থাকতে পারে: let errorMessage = `HTTP Error: ${response.status}`; try { const errorBody = await response.json(); errorMessage = errorBody.message || errorMessage; } catch { // JSON parse error ignore } throw new Error(errorMessage); } // 204 No Content — body নেই: if (response.status === 204) return null; return await response.json(); } catch (error) { if (error.name === "TypeError") { // Network error: Internet বন্ধ, DNS fail, CORS throw new Error("নেটওয়ার্ক সমস্যা — ইন্টারনেট চেক করুন"); } throw error; // HTTP error আবার throw } } // ===== Error Type-অনুযায়ী সামলানো ===== async function apiCall(endpoint) { try { const data = await goodFetch(`/api/${endpoint}`); return data; } catch (error) { if (error.message.includes("401")) { redirectToLogin(); } else if (error.message.includes("404")) { showNotFound(); } else if (error.message.includes("নেটওয়ার্ক")) { showOfflineMessage(); } else { showGenericError(error.message); } return null; } }

Timeout ও AbortController — Request বাতিল করা Abort

// ===== AbortController ===== const controller = new AbortController(); const { signal } = controller; // Fetch-এ signal পাঠাও: const fetchPromise = fetch("/api/large-data", { signal }); // ৫ সেকেন্ড পরে বাতিল: const timeoutId = setTimeout(() => controller.abort(), 5000); try { const response = await fetchPromise; clearTimeout(timeoutId); // সফল হলে timeout cancel const data = await response.json(); console.log(data); } catch (error) { if (error.name === "AbortError") { console.log("Request বাতিল করা হয়েছে (Timeout)"); } else { console.log("Error:", error.message); } } // ===== Reusable Timeout Fetch ===== async function fetchWithTimeout(url, options = {}, timeout = 5000) { const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), timeout); try { const response = await fetch(url, { ...options, signal: controller.signal, }); clearTimeout(timer); if (!response.ok) throw new Error(`HTTP ${response.status}`); return await response.json(); } catch (error) { clearTimeout(timer); if (error.name === "AbortError") { throw new Error(`Request timeout (${timeout}ms)`); } throw error; } } // ব্যবহার: const data = await fetchWithTimeout("/api/data", {}, 3000); // ===== User action-এ cancel — Search-এ ===== let searchController = null; async function search(query) { // আগের search বাতিল: searchController?.abort(); searchController = new AbortController(); try { const response = await fetch(`/api/search?q=${query}`, { signal: searchController.signal, }); const results = await response.json(); showResults(results); } catch (error) { if (error.name !== "AbortError") { showError(error.message); } } }

🔷 Reusable API Client — বাস্তব প্রজেক্ট Pattern

বাস্তব প্রজেক্টে প্রতিটি component-এ আলাদাভাবে fetch() না লিখে একটি Reusable API Client তৈরি করা ভালো অভ্যাস।

API Client Class API Client

class ApiClient { #baseURL; #defaultHeaders; #timeout; constructor(baseURL, options = {}) { this.#baseURL = baseURL; this.#timeout = options.timeout ?? 10000; this.#defaultHeaders = { "Content-Type": "application/json", "Accept": "application/json", ...options.headers, }; } // Auth token সেট করা: setAuthToken(token) { this.#defaultHeaders["Authorization"] = `Bearer ${token}`; } // Token সরানো (logout): clearAuthToken() { delete this.#defaultHeaders["Authorization"]; } // মূল request method: async #request(endpoint, options = {}) { const url = `${this.#baseURL}${endpoint}`; const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), this.#timeout); try { const response = await fetch(url, { ...options, headers: { ...this.#defaultHeaders, ...options.headers }, signal: controller.signal, }); clearTimeout(timer); if (!response.ok) { const error = await response.json().catch(() => ({})); throw new Error(error.message || `HTTP ${response.status}`); } if (response.status === 204) return null; return await response.json(); } catch (error) { clearTimeout(timer); if (error.name === "AbortError") { throw new Error("Request timeout"); } throw error; } } // HTTP Methods: get(endpoint, params = {}) { const query = new URLSearchParams(params).toString(); const url = query ? `${endpoint}?${query}` : endpoint; return this.#request(url, { method: "GET" }); } post(endpoint, data) { return this.#request(endpoint, { method: "POST", body: JSON.stringify(data), }); } put(endpoint, data) { return this.#request(endpoint, { method: "PUT", body: JSON.stringify(data), }); } patch(endpoint, data) { return this.#request(endpoint, { method: "PATCH", body: JSON.stringify(data), }); } delete(endpoint) { return this.#request(endpoint, { method: "DELETE" }); } } // ===== ব্যবহার ===== const api = new ApiClient("https://api.example.com", { timeout: 8000, }); // Login করার পরে: api.setAuthToken("eyJhbGci..."); // GET — query params সহ: const users = await api.get("/users", { page: 1, limit: 10 }); // POST: const newUser = await api.post("/users", { name: "করিম", email: "karim@example.com", }); // PATCH: const updated = await api.patch("/users/1", { name: "নতুন নাম" }); // DELETE: await api.delete("/users/1");

URLSearchParams — Query String তৈরি URLSearchParams

// Query String সহজে তৈরি: const params = new URLSearchParams({ search: "বাংলা JavaScript", page: 1, limit: 20, sort: "desc", }); console.log(params.toString()); // → search=%E0%A6%AC%E0%A6%BE%E0%A6%82%E0%A6%B2%E0%A6%BE+JavaScript&page=1&limit=20&sort=desc const url = `https://api.example.com/posts?${params}`; const response = await fetch(url); // URL থেকে params পড়া: const searchParams = new URLSearchParams(window.location.search); console.log(searchParams.get("page")); // → "1" console.log(searchParams.get("search")); // → "বাংলা JavaScript" // Params-এ মান যোগ, পরিবর্তন, মুছে ফেলা: params.append("tag", "javascript"); // একই key-এ নতুন value যোগ params.set("page", 2); // override params.delete("sort"); console.log(params.has("limit")); // → true

🔷 CORS, Authentication ও Best Practices

CORS — Cross-Origin Resource Sharing CORS

// CORS Error — Browser Console-এ: // Access to fetch at 'https://api.other.com' from origin 'https://myapp.com' // has been blocked by CORS policy // ===== CORS-এর সাধারণ সমাধান ===== // ১. credentials: "include" — Cookie পাঠাতে হলে: const response = await fetch("https://api.example.com/user", { credentials: "include", // Cookie ও Auth header পাঠাবে }); // Server-এ: Access-Control-Allow-Credentials: true // ২. mode নির্দিষ্ট করা: const response2 = await fetch(url, { mode: "cors", // Cross-origin allowed (default) // mode: "same-origin" // শুধু same-origin // mode: "no-cors" // Response পড়া যাবে না, কিন্তু request যাবে }); // ৩. Preflight — Browser OPTIONS request পাঠায়: // Custom header বা JSON body থাকলে browser আগে OPTIONS পাঠায়। // Server-কে OPTIONS-এ সঠিক CORS header দিতে হবে। // ===== Development-এ CORS Proxy ===== // Vite config: // server: { // proxy: { // "/api": { target: "https://backend.com", changeOrigin: true } // } // }

Authentication Patterns — JWT ও API Key Auth

// ===== JWT (Bearer Token) ===== async function login(email, password) { const response = await fetch("/api/auth/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password }), }); if (!response.ok) throw new Error("Login ব্যর্থ"); const { token, refreshToken } = await response.json(); // Token সংরক্ষণ: localStorage.setItem("token", token); localStorage.setItem("refreshToken", refreshToken); return token; } // Authenticated Request: async function authFetch(url, options = {}) { const token = localStorage.getItem("token"); return fetch(url, { ...options, headers: { ...options.headers, Authorization: token ? `Bearer ${token}` : "", }, }); } // Token Refresh — 401 হলে: async function fetchWithRefresh(url, options = {}) { let response = await authFetch(url, options); if (response.status === 401) { // Token expired — refresh করো: const refreshToken = localStorage.getItem("refreshToken"); const refreshRes = await fetch("/api/auth/refresh", { method: "POST", body: JSON.stringify({ refreshToken }), headers: { "Content-Type": "application/json" }, }); if (refreshRes.ok) { const { token } = await refreshRes.json(); localStorage.setItem("token", token); // নতুন token দিয়ে আবার চেষ্টা: response = await authFetch(url, options); } else { // Refresh-ও fail — Logout: localStorage.clear(); redirectToLogin(); } } return response; } // ===== API Key ===== const response = await fetch("https://api.example.com/data", { headers: { "X-API-Key": "my-api-key-here", // অথবা: "Authorization": "ApiKey my-key" }, });

API-র Best Practices Best Practices

// ১. Loading State — UI-তে: async function fetchWithState(url) { showLoader(); try { const response = await fetch(url); if (!response.ok) throw new Error(`HTTP ${response.status}`); const data = await response.json(); showData(data); return data; } catch (error) { showError(error.message); return null; } finally { hideLoader(); // সবসময় } } // ২. Retry Logic — ব্যর্থ হলে আবার চেষ্টা: async function fetchWithRetry(url, options = {}, maxRetries = 3) { for (let attempt = 1; attempt <= maxRetries; attempt++) { try { const response=await fetch(url, options); if (!response.ok && response.status>= 500) { throw new Error(`Server Error: ${response.status}`); } return response; } catch (error) { if (attempt === maxRetries) throw error; // Exponential backoff: const delay = Math.min(1000 * 2 ** attempt, 10000); console.log(`${attempt} নম্বর চেষ্টা ব্যর্থ, ${delay}ms পরে আবার...`); await new Promise(resolve => setTimeout(resolve, delay)); } } } // ৩. Caching — একই request বারবার না করা: const cache = new Map(); async function cachedFetch(url, ttl = 60000) { const cached = cache.get(url); if (cached && Date.now() - cached.timestamp < ttl) { console.log("Cache থেকে!"); return cached.data; } const response=await fetch(url); const data=await response.json(); cache.set(url, { data, timestamp: Date.now() }); return data; }

🔷 দ্রুত রেফারেন্স — Working with APIs

XMLHttpRequest বনাম Fetch API XHR vs Fetch

বিষয় XMLHttpRequest Fetch API
API ধরন Event-based, Callback Promise-based ✅
Syntax verbose, জটিল পরিষ্কার ✅
async/await ❌ সরাসরি নেই ✅ পুরোপুরি
Progress Tracking ✅ upload.onprogress ⚠️ Streams API দরকার
Request Abort ✅ xhr.abort() ✅ AbortController
Browser Support সব browser Modern browser ✅
কখন ব্যবহার করবে File upload progress, পুরানো codebase সব ক্ষেত্রে ✅

সাধারণ ভুল ও সমাধান Common Mistakes

ভুল সমস্যা সমাধান
fetch(url)-এ response.ok চেক নেই 404/500-এও সফল মনে হয় if (!response.ok) throw new Error(...)
Body দুবার পড়া TypeError: body used already response.clone() ব্যবহার করো
POST-এ Content-Type নেই Server JSON parse করতে পারে না headers: {"Content-Type": "application/json"}
FormData-এ Content-Type দেওয়া Boundary missing — server parse করতে পারে না FormData-এ Content-Type দেবে না — browser নিজে দেবে
Timeout implement নেই Request অনন্তকাল ঝুলতে পারে AbortController + setTimeout
Token localStorage-এ (XSS ঝুঁকি) Script injection করলে token চুরি HttpOnly Cookie ব্যবহার করো

Production-ready Fetch চেকলিস্ট Checklist

চেকলিস্ট কেন দরকার?
response.ok চেক করা HTTP 4xx/5xx সামলাতে
✅ try/catch দিয়ে Network error সামলানো Offline বা DNS failure
✅ AbortController দিয়ে Timeout Slow network-এ infinite wait এড়াতে
✅ Loading state দেখানো User experience উন্নত করতে
✅ Error message user-কে দেখানো Silent failure এড়াতে
✅ Sensitive data log না করা Security
✅ API URL environment variable-এ Dev/Prod পরিবর্তন সহজ

🧠 নিজেকে যাচাই করো

1. fetch() কী return করে?

2. response.json() কী করে?

3. HTTP status 404 মানে?

✏️ Task — এখন তুমি করো

GitHub API থেকে user info আনো: https://api.github.com/users/octocat

ধাপ 15🏗️ Real Project — Interactive Portfolio

Portfolio-এ Weather API দিয়ে আবহাওয়া দেখাও।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio-এ Weather API থেকে তোমার শহরের আবহাওয়া দেখাও।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

🏛️ JavaScript Classes — সম্পূর্ণ নোট

এই সেকশনে JavaScript-এর Classes-এর সব দিক — Class Declaration, Constructor, Methods, Inheritance, Static, Private Fields, Getter/Setter, এবং Mixins — বাংলায় উদাহরণসহ বিস্তারিত আলোচনা করা হয়েছে।


🔷 Class কী ও Prototype-এর সম্পর্ক

JavaScript-এ Class হলো ES6-এর Syntactic Sugar — আসলে ভেতরে Prototype-ভিত্তিক Inheritance-ই কাজ করছে। typeof MyClass === "function" — Class আসলে একটি বিশেষ function।

বিষয় Constructor Function (পুরানো) Class (আধুনিক)
Syntax verbose, ছড়ানো ✅ পরিষ্কার, এক জায়গায়
Hoisting ✅ Hoisted ❌ TDZ-এ (আগে ব্যবহার নয়)
Strict Mode Manual ✅ স্বয়ংক্রিয়
Inheritance জটিল prototype chain extends সহজ
Private Field Convention (#_) বা Closure ✅ Native #field
// Constructor Function (পুরানো): function Person(name, age) { this.name = name; this.age = age; } Person.prototype.greet = function() { return `হ্যালো, আমি ${this.name}`; }; // Class (আধুনিক — একই কাজ): class PersonClass { constructor(name, age) { this.name = name; this.age = age; } greet() { return `হ্যালো, আমি ${this.name}`; } } // প্রমাণ — Class আসলে function: console.log(typeof PersonClass); // → "function" console.log(PersonClass === PersonClass.prototype.constructor); // → true // new ছাড়া call করলে: // PersonClass("করিম", 25); // → TypeError: Cannot call a class as a function

🔷 Class Declaration ও Constructor

Class Declaration ও Class Expression Declaration

// ১. Class Declaration: class Student { constructor(name, roll, score) { // Instance properties: this.name = name; this.roll = roll; this.score = score; } // Method — prototype-এ যায়: introduce() { return `আমি ${this.name}, রোল ${this.roll}`; } getGrade() { if (this.score >= 80) return "A+"; if (this.score >= 70) return "A"; if (this.score >= 60) return "A-"; if (this.score >= 50) return "B"; if (this.score >= 33) return "C"; return "F"; } } const s1 = new Student("করিম", 1, 85); const s2 = new Student("রাহেলা", 2, 92); console.log(s1.introduce()); // → আমি করিম, রোল 1 console.log(s2.getGrade()); // → A+ // Method prototype-এ থাকে — সব instance share করে: console.log(s1.introduce === s2.introduce); // → true ✅ // ২. Class Expression (Named বা Anonymous): const Animal = class { constructor(name) { this.name = name; } speak() { return `${this.name} শব্দ করে`; } }; // Named Class Expression: const Vehicle = class Car { getType() { return "গাড়ি"; } // Car নামটি শুধু class-এর ভেতরে দৃশ্যমান }; // ৩. Constructor-এ Validation: class BankAccount { constructor(owner, balance) { if (!owner || typeof owner !== "string") { throw new TypeError("মালিকের নাম String হতে হবে"); } if (typeof balance !== "number" || balance < 0) { throw new RangeError("ব্যালেন্স ঋণাত্মক হতে পারবে না"); } this.owner=owner; this.balance=balance; } } try { new BankAccount("করিম", -100); } catch (e) { console.log(e.message); // → ব্যালেন্স ঋণাত্মক হতে পারবে না }

🔷 Methods, Getter ও Setter

Instance Methods ও Method Chaining Methods

class Cart { constructor() { this.items = []; this.discount = 0; } // Instance Methods: addItem(name, price, qty = 1) { this.items.push({ name, price, qty }); return this; // Method Chaining-এর জন্য } removeItem(name) { this.items = this.items.filter(i => i.name !== name); return this; } applyDiscount(percent) { this.discount = percent; return this; } getTotal() { const subtotal = this.items.reduce((sum, i) => sum + i.price * i.qty, 0); return subtotal * (1 - this.discount / 100); } summary() { console.log(`আইটেম: ${this.items.length}, মোট: ৳${this.getTotal()}`); return this; } } // Method Chaining: const cart = new Cart() .addItem("চাল", 650, 2) .addItem("ডাল", 120, 1) .applyDiscount(10) .summary(); // → আইটেম: 2, মোট: ৳1278

Getter ও Setter get / set

class Temperature { #celsius; // Private field constructor(celsius) { this.#celsius = celsius; } // Getter — property-র মতো পড়া: get celsius() { return this.#celsius; } get fahrenheit() { return this.#celsius * 9 / 5 + 32; } get kelvin() { return this.#celsius + 273.15; } // Setter — validation সহ লেখা: set celsius(value) { if (value < -273.15) { throw new RangeError("পরম শূন্যের (-273.15°C) নিচে নামা সম্ভব নয়"); } this.#celsius=value; } set fahrenheit(value) { this.celsius=(value - 32) * 5 / 9; // setter call করছে } } const temp=new Temperature(0); // ০°C (বরফ গলার তাপমাত্রা) // Getter — method call না করেই: console.log(temp.celsius); // → 0 console.log(temp.fahrenheit); // → 32 console.log(temp.kelvin); // → 273.15 // Setter: temp.celsius=100; // ১০০°C (পানির স্ফুটনাঙ্ক) console.log(temp.fahrenheit); // → 212 try { temp.celsius=-300; // → RangeError } catch (e) { console.log(e.message); }

Static Methods ও Static Properties static

class MathUtils { // Static property: static PI = 3.14159265358979; static #instanceCount = 0; // Private Static constructor() { MathUtils.#instanceCount++; } // Static Methods — instance ছাড়া call করা যায়: static add(a, b) { return a + b; } static multiply(a, b) { return a * b; } static factorial(n) { return n <= 1 ? 1 : n * MathUtils.factorial(n - 1); } static isPrime(n) { if (n < 2) return false; for (let i=2; i <=Math.sqrt(n); i++) { if (n % i===0) return false; } return true; } static getInstanceCount() { return MathUtils.#instanceCount; } } // Instance ছাড়াই ব্যবহার: console.log(MathUtils.add(5, 3)); // → 8 console.log(MathUtils.factorial(5)); // → 120 console.log(MathUtils.isPrime(17)); // → true console.log(MathUtils.PI); // → 3.14159265358979 // Factory Static Method — সেরা ব্যবহার: class User { constructor(name, role) { this.name=name; this.role=role; } static createAdmin(name) { return new User(name, "admin" ); } static createGuest() { return new User("অতিথি", "guest" ); } } const admin=User.createAdmin("করিম"); const guest=User.createGuest(); console.log(admin.role); // → admin

🔷 Private Fields ও Methods — #

class BankAccount { // Private Fields — বাইরে থেকে access নেই: #balance; #pin; #transactions = []; #isLocked = false; constructor(owner, initialBalance, pin) { this.owner = owner; // Public this.#balance = initialBalance; this.#pin = pin; } // Private Method: #validatePin(pin) { return this.#pin === pin; } #logTransaction(type, amount) { this.#transactions.push({ type, amount, date: new Date().toLocaleDateString("bn-BD"), balance: this.#balance, }); } // Public Methods: deposit(amount) { if (this.#isLocked) throw new Error("Account locked"); if (amount <= 0) throw new RangeError("পরিমাণ ধনাত্মক হতে হবে"); this.#balance +=amount; this.#logTransaction("জমা", amount); return this; } withdraw(pin, amount) { if (!this.#validatePin(pin)) { this.#isLocked=true; throw new Error("ভুল PIN — Account locked"); } if (amount> this.#balance) throw new Error("পর্যাপ্ত ব্যালেন্স নেই"); this.#balance -= amount; this.#logTransaction("উত্তোলন", amount); return this; } getStatement() { return { owner: this.owner, balance: this.#balance, transactions: [...this.#transactions], }; } // Getter: get balance() { return this.#balance; } } const account = new BankAccount("করিম", 5000, 1234); account.deposit(1000).deposit(500); account.withdraw(1234, 200); console.log(account.balance); // → 6300 ✅ // console.log(account.#balance); // → SyntaxError ✅ (বাইরে নেই!) console.log(account.getStatement()); // Private Field-এর in চেক: console.log(#balance in account); // → true (class-এর ভেতরে এভাবে চেক করা যায়)

🔷 Inheritance — extendssuper

extends ও super-এর মূল ব্যবহার extends / super

// Parent Class: class Animal { #name; #sound; constructor(name, sound) { this.#name = name; this.#sound = sound; this.isAlive = true; } speak() { return `${this.#name} বলছে: ${this.#sound}`; } eat(food) { return `${this.#name} ${food} খাচ্ছে`; } get name() { return this.#name; } toString() { return `[Animal: ${this.#name}]`; } } // Child Class: class Dog extends Animal { #breed; constructor(name, breed) { super(name, "ঘেউ ঘেউ"); // Parent constructor অবশ্যই আগে this.#breed = breed; // তারপর নিজের property } // Override — Parent-এর method বদলানো: speak() { const parentSpeech = super.speak(); // Parent-এর version return `${parentSpeech}! (${this.#breed} প্রজাতির)`; } fetch(item) { return `${this.name} ${item} নিয়ে এলো`; } get breed() { return this.#breed; } } class Cat extends Animal { constructor(name) { super(name, "মিঁয়াউ"); this.isIndoor = true; } purr() { return `${this.name} গরগর করছে`; } } const dog = new Dog("রেক্স", "জার্মান শেপার্ড"); const cat = new Cat("মিষ্টি"); console.log(dog.speak()); // → রেক্স বলছে: ঘেউ ঘেউ! (জার্মান শেপার্ড প্রজাতির) console.log(dog.eat("মাংস")); // → রেক্স মাংস খাচ্ছে (Parent-এর method) console.log(dog.fetch("বল")); // → রেক্স বল নিয়ে এলো console.log(cat.purr()); // → মিষ্টি গরগর করছে // instanceof: console.log(dog instanceof Dog); // → true console.log(dog instanceof Animal); // → true (Parent-ও) console.log(cat instanceof Dog); // → false

Multi-level Inheritance ও Method Override Multi-level

class Shape { constructor(color = "সাদা") { this.color = color; } area() { return 0; } perimeter() { return 0; } describe() { return `${this.color} রঙের আকৃতি, ক্ষেত্রফল: ${this.area().toFixed(2)}`; } } class Rectangle extends Shape { constructor(width, height, color) { super(color); this.width = width; this.height = height; } area() { return this.width * this.height; } perimeter() { return 2 * (this.width + this.height); } } class Square extends Rectangle { constructor(side, color) { super(side, side, color); // Rectangle-এর constructor } // Override: describe() { return `${this.color} রঙের বর্গক্ষেত্র, বাহু: ${this.width}`; } } class Circle extends Shape { constructor(radius, color) { super(color); this.radius = radius; } area() { return Math.PI * this.radius ** 2; } perimeter() { return 2 * Math.PI * this.radius; } } const rect = new Rectangle(5, 3, "নীল"); const square = new Square(4, "লাল"); const circle = new Circle(7, "সবুজ"); console.log(rect.describe()); // → নীল রঙের আকৃতি, ক্ষেত্রফল: 15.00 console.log(square.describe()); // → লাল রঙের বর্গক্ষেত্র, বাহু: 4 console.log(circle.area().toFixed(2)); // → 153.94 // Polymorphism: const shapes = [rect, square, circle]; shapes.forEach(s => console.log(s.describe()));

Abstract Class Pattern ও Mixin Abstract / Mixin

// JavaScript-এ Abstract Class নেই — Pattern দিয়ে তৈরি: class AbstractVehicle { constructor(brand) { if (new.target === AbstractVehicle) { throw new Error("AbstractVehicle সরাসরি instantiate করা যাবে না"); } this.brand = brand; } // Abstract Method — Subclass-কে implement করতে হবে: getFuelType() { throw new Error("getFuelType() implement করতে হবে"); } describe() { return `${this.brand} — জ্বালানি: ${this.getFuelType()}`; } } class ElectricCar extends AbstractVehicle { getFuelType() { return "বিদ্যুৎ"; } } class PetrolCar extends AbstractVehicle { getFuelType() { return "পেট্রোল"; } } // new AbstractVehicle("Toyota"); // → Error ✅ const tesla = new ElectricCar("Tesla"); console.log(tesla.describe()); // → Tesla — জ্বালানি: বিদ্যুৎ // ===== Mixin — Multiple Inheritance-এর বিকল্প ===== // JavaScript-এ একটি class একটিই class extend করতে পারে। // Mixin দিয়ে একাধিক behavior যোগ করা যায়: const Serializable = (Base) => class extends Base { serialize() { return JSON.stringify(this); } static deserialize(json) { return Object.assign(new this(), JSON.parse(json)); } }; const Timestamped = (Base) => class extends Base { constructor(...args) { super(...args); this.createdAt = new Date().toISOString(); } }; const Validatable = (Base) => class extends Base { validate() { return Object.keys(this).every(key => this[key] !== null && this[key] !== undefined); } }; // একাধিক Mixin একসাথে: class UserModel extends Serializable(Timestamped(Validatable(class {}))) { constructor(name, email) { super(); this.name = name; this.email = email; } } const user = new UserModel("করিম", "karim@example.com"); console.log(user.validate()); // → true console.log(user.createdAt); // → ISO timestamp console.log(user.serialize()); // → JSON string

🔷 দ্রুত রেফারেন্স — Classes

Class Syntax এক নজরে Syntax

Feature Syntax কাজ
Class Declaration class Foo {} Class তৈরি
Constructor constructor(args) {} Instance তৈরির সময় চলে
Instance Method methodName() {} সব instance-এ পাওয়া যায়
Static Method static methodName() {} Class-এ সরাসরি, instance-এ নয়
Getter get propName() {} Property-র মতো পড়া
Setter set propName(val) {} Property-র মতো লেখা (validation)
Private Field #fieldName Class-এর বাইরে access নেই
Private Method #methodName() {} Class-এর বাইরে call নেই
Inheritance class B extends A {} A-র সব feature নেওয়া
Super Constructor super(args) Parent constructor call
Super Method super.method() Parent-এর method call
Abstract Check if (new.target === Base) Direct instantiate রোধ

সাধারণ ভুল ও সমাধান Common Mistakes

ভুল সমস্যা সমাধান
extends-এ super() না দেওয়া ReferenceError: Must call super before this constructor-এর প্রথম লাইনে super() দাও
class-এর আগে ব্যবহার ReferenceError (TDZ) class declaration-এর পরে ব্যবহার করো
Method-এ Arrow Function — this Arrow Class Field হিসেবে না দিলে this হারাতে পারে Callback-এ bind() বা Arrow Class Field
#field ঘোষণা না করে ব্যবহার SyntaxError class body-তে আগে declare করো

🧠 নিজেকে যাচাই করো

1. constructor() কী করে?

2. extends কী করে?

3. super() কী করে?

✏️ Task — এখন তুমি করো

Project class বানাও। Portfolio class বানাও যেটা Project-এর array রাখে।

ধাপ 16🏗️ Real Project — Interactive Portfolio

Class দিয়ে Portfolio management system বানাও।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio, Project, Skill — তিনটা class বানাও। Instance তৈরি করো।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

🔄 Iterators and Generators — সম্পূর্ণ নোট

এই সেকশনে JavaScript-এর Iterators ও Generators — Iteration Protocol, Custom Iterator, Generator Function, yield, Generator-এর ব্যবহারিক প্রয়োগ — বাংলায় উদাহরণসহ বিস্তারিত আলোচনা করা হয়েছে।


🔷 Iteration Protocol — Iterable ও Iterator

Iteration Protocol হলো JavaScript-এর নিয়মকানুন যা নির্ধারণ করে কোন Object-কে for...of, Spread (...), Destructuring দিয়ে iterate করা যাবে।

Protocol প্রয়োজনীয় ফেরত দেয় কোথায় ব্যবহার হয়
Iterable [Symbol.iterator]() method Iterator object for...of, Spread, Destructuring
Iterator next() method { value, done } একের পর এক মান দেওয়া
Async Iterable [Symbol.asyncIterator]() Promise<{value, done}> for await...of
// Built-in Iterator দেখা: const arr = ["ক", "খ", "গ"]; const iterator = arr[Symbol.iterator](); // Iterator বের করা console.log(iterator.next()); // → { value: "ক", done: false } console.log(iterator.next()); // → { value: "খ", done: false } console.log(iterator.next()); // → { value: "গ", done: false } console.log(iterator.next()); // → { value: undefined, done: true } // String Iterator: const strIt = "হ্যালো"[Symbol.iterator](); console.log(strIt.next()); // → { value: "হ", done: false } // for...of আসলে Iterator protocol ব্যবহার করে: for (const char of "বাংলা") { console.log(char); // → ব, া, ং, ল, া } // Spread-ও Iterator protocol: console.log([..."ABC"]); // → ["A", "B", "C"] // Destructuring-ও Iterator protocol: const [first, , third] = new Set([10, 20, 30, 40]); console.log(first, third); // → 10 30

🔷 Custom Iterator তৈরি

নিজের Iterable Object Custom Iterable

// Range Object — from থেকে to পর্যন্ত: class Range { constructor(from, to, step = 1) { this.from = from; this.to = to; this.step = step; } // Iterable Protocol: [Symbol.iterator]() { let current = this.from; const { to, step } = this; // Iterator Object ফেরত: return { next() { if (current <= to) { const value=current; current +=step; return { value, done: false }; } return { value: undefined, done: true }; }, // Optional: return() — early exit cleanup return(value) { console.log("Iterator বন্ধ হচ্ছে"); return { value, done: true }; } }; } } // ব্যবহার: const range=new Range(1, 10, 2); // 1, 3, 5, 7, 9 for (const n of range) { console.log(n); // → 1, 3, 5, 7, 9 } console.log([...range]); // → [1, 3, 5, 7, 9] console.log([...new Range(1, 5)]); // → [1, 2, 3, 4, 5] // Early exit — return() call হয়: for (const n of new Range(1, 100)) { if (n> 5) break; // → "Iterator বন্ধ হচ্ছে" console.log(n); } // Infinite Iterator: const naturals = { [Symbol.iterator]() { let n = 1; return { next() { return { value: n++, done: false }; } }; } }; // take utility: function take(iterable, count) { const result = []; for (const item of iterable) { result.push(item); if (result.length >= count) break; } return result; } console.log(take(naturals, 10)); // → [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Iterator-এ নিজে Iterator হওয়া — Self-referential Self-referential

// Iterator যে নিজেও Iterable — সরলতার জন্য: class Counter { constructor(limit) { this.limit = limit; this.current = 0; } // নিজেই Iterator: next() { if (this.current < this.limit) { return { value: this.current++, done: false }; } return { value: undefined, done: true }; } // নিজেকেই Iterable হিসেবে return করে: [Symbol.iterator]() { return this; } } const counter=new Counter(5); // for...of দিয়ে: for (const n of counter) { console.log(n); // → 0, 1, 2, 3, 4 } // একবার শেষ হলে আর চলে না (state shared): console.log([...counter]); // → [] (ইতিমধ্যে শেষ!)

🔷 Generators — function*yield

Generator Function (function*) হলো এমন function যা মাঝপথে থামতে (yield) এবং আবার শুরু হতে (next()) পারে। এটি স্বয়ংক্রিয়ভাবে Iterator Protocol implement করে।

Generator Function-এর মূল ধারণা Basics

// Generator Function: function* simpleGen() { console.log("প্রথম yield-এর আগে"); yield 1; console.log("দ্বিতীয় yield-এর আগে"); yield 2; console.log("তৃতীয় yield-এর আগে"); yield 3; console.log("শেষ — generator সম্পন্ন"); } const gen = simpleGen(); // Generator Object তৈরি (এখনো চলেনি!) console.log(gen.next()); // → প্রথম yield-এর আগে → { value: 1, done: false } console.log(gen.next()); // → দ্বিতীয় yield-এর আগে → { value: 2, done: false } console.log(gen.next()); // → তৃতীয় yield-এর আগে → { value: 3, done: false } console.log(gen.next()); // → শেষ — generator সম্পন্ন → { value: undefined, done: true } console.log(gen.next()); // → { value: undefined, done: true } (এর পরে সবসময়) // for...of দিয়ে সহজে: for (const val of simpleGen()) { console.log(val); // → 1, 2, 3 } // Spread দিয়ে: console.log([...simpleGen()]); // → [1, 2, 3]

yield* — অন্য Generator-কে Delegate করা yield*

// yield* = অন্য Iterable-এর সব মান yield করে: function* firstThree() { yield 1; yield 2; yield 3; } function* combined() { yield* firstThree(); // firstThree-এর সব yield* [4, 5, 6]; // Array-ও yield* "ABC"; // String-এর প্রতিটি character yield 100; // সরাসরি } console.log([...combined()]); // → [1, 2, 3, 4, 5, 6, "A", "B", "C", 100] // Recursive Generator — Tree Traversal: function* flatten(arr) { for (const item of arr) { if (Array.isArray(item)) { yield* flatten(item); // Recursive! } else { yield item; } } } const nested = [1, [2, [3, [4]]], 5, [6, 7]]; console.log([...flatten(nested)]); // → [1, 2, 3, 4, 5, 6, 7]

next()-এ মান পাঠানো — দুমুখী যোগাযোগ Two-way

// next(value) — Generator-এ মান পাঠানো: function* calculator() { const x = yield "প্রথম সংখ্যা দাও:"; // yield-এর মান = next()-এর argument const y = yield "দ্বিতীয় সংখ্যা দাও:"; const op = yield "অপারেশন (+, -, *, /):"; switch (op) { case "+": return x + y; case "-": return x - y; case "*": return x * y; case "/": return x / y; default: return NaN; } } const calc = calculator(); console.log(calc.next()); // → { value: "প্রথম সংখ্যা দাও:", done: false } console.log(calc.next(10)); // → { value: "দ্বিতীয় সংখ্যা দাও:", done: false } | x=10 console.log(calc.next(5)); // → { value: "অপারেশন:", done: false } | y=5 console.log(calc.next("+")); // → { value: 15, done: true } | op="+" // Generator-এ Error throw করা: function* safeGen() { try { const value = yield "মান দাও:"; console.log("পেয়েছি:", value); } catch (error) { console.log("Generator-এ Error:", error.message); yield "Error সামলানো হয়েছে"; } } const sg = safeGen(); sg.next(); // শুরু sg.throw(new Error("ইচ্ছাকৃত Error")); // → Generator-এ Error: ইচ্ছাকৃত Error // Generator বন্ধ করা: function* infiniteGen() { let i = 0; while (true) yield i++; } const ig = infiniteGen(); console.log(ig.next().value); // → 0 console.log(ig.return("বন্ধ")); // → { value: "বন্ধ", done: true } console.log(ig.next().value); // → undefined (done)

🔷 Generator-এর Practical ব্যবহার

Infinite Sequence ও Lazy Evaluation Infinite / Lazy

// Infinite Fibonacci: function* fibonacci() { let [a, b] = [0, 1]; while (true) { yield a; [a, b] = [b, a + b]; } } console.log(take(fibonacci(), 8)); // → [0, 1, 1, 2, 3, 5, 8, 13] // Unique ID Generator: function* idGen(prefix = "ID") { let id = 1; while (true) { yield `${prefix}-${String(id++).padStart(5, "0")}`; } } const userId = idGen("USR"); const orderId = idGen("ORD"); console.log(userId.next().value); // → USR-00001 console.log(userId.next().value); // → USR-00002 console.log(orderId.next().value); // → ORD-00001 // Prime Number Generator — Lazy: function* primes() { const found = []; let candidate = 2; while (true) { const isPrime = found.every(p => candidate % p !== 0); if (isPrime) { found.push(candidate); yield candidate; } candidate++; } } console.log(take(primes(), 10)); // → [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

Async Generator — for await...of Async Generator

// Async Generator — async function* : async function* fetchPages(baseUrl, totalPages) { for (let page = 1; page <= totalPages; page++) { const response=await fetch(`${baseUrl}?page=${page}`); const data=await response.json(); yield data; // প্রতিটি page একে একে yield } } // for await...of দিয়ে: async function processAllPages() { let allItems=[]; for await (const pageData of fetchPages("/api/items", 5)) { allItems=[...allItems, ...pageData.items]; console.log(`Page লোড হলো: ${pageData.items.length} আইটেম`); } return allItems; } //=====Generator Pipeline=====function* map(iterable, fn) { for (const item of iterable) yield fn(item); } function* filter(iterable, pred) { for (const item of iterable) { if (pred(item)) yield item; } } function* take(iterable, n) { let count=0; for (const item of iterable) { if (count++>= n) return; yield item; } } // Pipeline — Lazy, মেমোরি দক্ষ: const result = [ ...take( filter( map(naturals, n => n * n), // সব বর্গ (infinite) n => n % 2 === 0 // জোড় বর্গ ), 5 // প্রথম ৫টি ) ]; console.log(result); // → [4, 16, 36, 64, 100]

Iterator Helpers — ES2025 ES2025

// ES2025-এ Iterator.prototype-এ method যোগ হয়েছে: // Iterator.from() — যেকোনো Iterable → Iterator: const iter = Iterator.from([1, 2, 3, 4, 5]); // .map(), .filter(), .take(), .drop() — Lazy: const result = Iterator.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) .filter(n => n % 2 === 0) // জোড় .map(n => n * n) // বর্গ .take(3) // প্রথম ৩ .toArray(); // Array-এ শেষ console.log(result); // → [4, 16, 36] // .reduce(), .forEach(), .some(), .every(): const sum = Iterator.from([1, 2, 3, 4, 5]).reduce((a, b) => a + b, 0); console.log(sum); // → 15

🔷 দ্রুত রেফারেন্স — Iterators and Generators

Iterator vs Generator তুলনা Comparison

বিষয় Custom Iterator Generator
Boilerplate বেশি — next(), return ম্যানুয়াল ✅ কম — yield করলেই হয়
State Management নিজে সামলাতে হয় ✅ স্বয়ংক্রিয় (pause/resume)
Infinite Sequence সম্ভব ✅ সহজ
Two-way Communication ✅ next(value)
Error Handling জটিল ✅ throw()
Async Support Manual ✅ async function*

কখন কী ব্যবহার করবে Decision Guide

পরিস্থিতি ব্যবহার করো
Custom data structure iterate করতে Custom Iterable ([Symbol.iterator])
Infinite sequence (ID, Fibonacci) Generator (function*)
Lazy data processing pipeline Generator chain (map, filter, take)
Async stream / API pagination Async Generator (async function*)
Nested array flatten Recursive Generator + yield*
Simple Array loop for...of বা forEach (Generator দরকার নেই)

🧠 নিজেকে যাচাই করো

1. Generator function কীভাবে define করে?

2. yield কী করে?

3. next() method কী return করে?

✏️ Task — এখন তুমি করো

Generator function বানাও যেটা fibonacci sequence generate করে।

ধাপ 17🏗️ Real Project — Interactive Portfolio

Iterator দিয়ে portfolio skills traverse করো।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio skills generator বানাও — একটা একটা করে দেখাবে।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

📦 Modules in JavaScript — সম্পূর্ণ নোট

এই সেকশনে JavaScript-এর Module System — CommonJS (require/module.exports), ES Modules (import/export), Dynamic Import, এবং Module-এর best practices — বাংলায় উদাহরণসহ বিস্তারিত আলোচনা করা হয়েছে।


🔷 Module কী ও কেন দরকার?

Module হলো JavaScript কোড ভাগ করার পদ্ধতি। প্রতিটি Module file নিজের scope-এ চলে — global scope দূষণ ছাড়াই code reuse ও maintainability নিশ্চিত করে।

বিষয় CommonJS ES Module (ESM)
Syntax require() / module.exports import / export
Loading Synchronous — runtime-এ Asynchronous — parse-time-এ (static)
Environment Node.js (.js) Browser + Node.js (.mjs বা type:"module")
Strict Mode Manual ✅ স্বয়ংক্রিয়
Tree Shaking ❌ কঠিন ✅ Static analysis সম্ভব
Dynamic Import runtime require() import() function

🔷 CommonJS — Node.js-এর Module System

module.exports ও require() CommonJS

// ===== math.js (export করা) ===== // একটি function export: function add(a, b) { return a + b; } function subtract(a, b) { return a - b; } function multiply(a, b) { return a * b; } const PI = 3.14159265358979; // একসাথে export: module.exports = { add, subtract, multiply, PI }; // ===== বিকল্প — exports object সরাসরি: // exports.add = (a, b) => a + b; // exports.PI = 3.14; // ⚠️ exports = {...} এভাবে দেবে না — reference হারায়! // ✅ module.exports = {...} ব্যবহার করো // ===== app.js (import করা) ===== const math = require("./math"); // পুরো object const { add, PI } = require("./math"); // Destructuring console.log(math.add(5, 3)); // → 8 console.log(add(5, 3)); // → 8 console.log(PI); // → 3.14159265358979 // Built-in modules: const path = require("path"); const fs = require("fs"); const http = require("http"); // npm packages: // const express = require("express"); // ===== Class export: // user.js class User { constructor(name) { this.name = name; } greet() { return `হ্যালো, ${this.name}`; } } module.exports = User; // Class সরাসরি // app.js const User = require("./user"); const u = new User("করিম"); console.log(u.greet());

require()-এর বৈশিষ্ট্য Features

// ১. Cache — একই module বারবার require করলে cache থেকে: const a = require("./math"); const b = require("./math"); // Cache থেকে — নতুন load নেই console.log(a === b); // → true (একই object) // ২. Dynamic require — runtime-এ: const moduleName = "path"; const dynamicMod = require(moduleName); // ✅ কাজ করে // ৩. Circular Dependency — সতর্ক থাকো: // a.js: const b = require("./b"); exports.name = "A"; // b.js: const a = require("./a"); exports.name = "B"; // Circular হলে partial export পাবে! // ৪. __dirname ও __filename — CommonJS-এ পাওয়া যায়: console.log(__dirname); // → /Users/.../project (current directory) console.log(__filename); // → /Users/.../project/app.js

🔷 ES Modules (ESM) — আধুনিক Module System

Named Export ও Import Named

// ===== math.js (Named Export) ===== export const PI = 3.14159265358979; export const E = 2.71828182845905; export function add(a, b) { return a + b; } export function subtract(a, b) { return a - b; } export function multiply(a, b) { return a * b; } export function divide(a, b) { if (b === 0) throw new Error("শূন্য দিয়ে ভাগ নয়"); return a / b; } // অথবা — শেষে একসাথে: function square(n) { return n * n; } function cube(n) { return n * n * n; } export { square, cube }; // Rename করে export: function internalHelper() { return "helper"; } export { internalHelper as helper }; // বাইরে "helper" নামে // ===== app.js (Named Import) ===== import { add, PI, divide } from "./math.js"; console.log(add(5, 3)); // → 8 console.log(PI); // → 3.14159265358979 // Rename করে import: import { add as sum, multiply as mul } from "./math.js"; console.log(sum(5, 3)); // → 8 // সব import করা: import * as math from "./math.js"; console.log(math.add(5, 3)); // → 8 console.log(math.PI); // → 3.14159...

Default Export ও Import Default

// ===== user.js (Default Export) ===== // Default export — প্রতি file-এ একটিই: export default class User { constructor(name, email) { this.name = name; this.email = email; } greet() { return `হ্যালো, আমি ${this.name}`; } } // Function default export: // export default function processData(data) { ... } // ===== app.js (Default Import) ===== // Default import-এ যেকোনো নাম দেওয়া যায়: import User from "./user.js"; import UserClass from "./user.js"; // একই file, ভিন্ন নাম — কাজ করবে const u = new User("করিম", "karim@example.com"); console.log(u.greet()); // → হ্যালো, আমি করিম // Named ও Default একসাথে: // utils.js: export default function mainFunction() { return "main"; } export const helper1 = () => "helper1"; export const helper2 = () => "helper2"; // import: import mainFn, { helper1, helper2 } from "./utils.js"; // default আগে, তারপর named

Re-export ও Module Aggregation Re-export

// ===== index.js — সব একজায়গা থেকে export ===== // (Barrel File / Public API Pattern) // Re-export — অন্য module-এর export forward করা: export { add, subtract } from "./math.js"; export { default as User } from "./user.js"; export * from "./utils.js"; export * as math from "./math.js"; // namespace-এ // ব্যবহার — সব এক জায়গা থেকে: import { add, User, math } from "./index.js"; // আলাদা আলাদা import করতে হচ্ছে না! // ===== Browser-এ ESM ===== // <script type="module" src="app.js"></script> // type="module" = ESM, Strict Mode, deferred // ESM-এ import.meta: console.log(import.meta.url); // current file URL console.log(import.meta.env); // Vite-এ env variables

🔷 Dynamic Import — import()

Dynamic Import (import()) হলো runtime-এ module load করার পদ্ধতি। Promise ফেরত দেয় — await দিয়ে ব্যবহার করা যায়। Code Splitting ও Lazy Loading-এর মূল হাতিয়ার।

// Static import — parse-time-এ: import { add } from "./math.js"; // সবসময় load হয় // Dynamic import — runtime-এ: const math = await import("./math.js"); // চাইলে load করো console.log(math.add(5, 3)); // → 8 // Default ও Named একসাথে: const { default: User, helper } = await import("./user.js"); const u = new User("করিম"); // ===== Code Splitting — Lazy Loading ===== // ভারী feature শুধু দরকারের সময়: const loadChartModule = async () => { const { Chart } = await import("./chart.js"); // ক্লিক করলে load return new Chart(); }; document.querySelector("#chart-btn").addEventListener("click", async () => { const chart = await loadChartModule(); chart.render("#canvas"); }); // ===== Conditional Loading ===== async function loadModule(lang) { // শুধু দরকারী language pack load: const messages = await import(`./locales/${lang}.js`); return messages.default; } const bnMessages = await loadModule("bn"); // বাংলা const enMessages = await loadModule("en"); // English // ===== Error Handling ===== try { const module = await import("./optional-feature.js"); module.init(); } catch (error) { console.log("Optional feature লোড হয়নি:", error.message); // fallback — সাধারণ কাজ করো } // ===== React-style Route-based Code Splitting ===== // const AdminPanel = React.lazy(() => import("./AdminPanel")); // এটাই Dynamic Import ব্যবহার করে!

🔷 দ্রুত রেফারেন্স — Modules

Export ও Import Syntax এক নজরে Syntax

কাজ CommonJS ES Module
Named export exports.fn = fn export function fn() {}
Default export module.exports = fn export default fn
Named import const {fn} = require("...") import { fn } from "..."
Default import const fn = require("...") import fn from "..."
All import const m = require("...") import * as m from "..."
Dynamic import const m = require(variable) const m = await import(variable)
Re-export require + exports export { fn } from "..."

সাধারণ ভুল ও সমাধান Common Mistakes

ভুল সমস্যা সমাধান
ESM-এ .js extension বাদ Browser-এ import fail import "./math.js" — extension দাও
exports = {...} Reference হারায়, কাজ করে না module.exports = {...}
CommonJS-এ top-level await SyntaxError ESM (.mjs) বা async IIFE ব্যবহার করো
Circular Dependency Partial/undefined export পাওয়া Dependency graph পরিষ্কার রাখো
Browser-এ type="module" নেই import/export SyntaxError <script type="module"> দাও

🧠 নিজেকে যাচাই করো

1. export কী করে?

2. import কী করে?

3. default export কতটা থাকতে পারে?

✏️ Task — এখন তুমি করো

portfolio.js ফাইলে data রাখো ও export করো। index.js-এ import করো।

ধাপ 18🏗️ Real Project — Interactive Portfolio

Module pattern দিয়ে Portfolio code organize করো।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio JS code modules-এ ভাগ করো।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

🧠 Memory Management — সম্পূর্ণ নোট

এই সেকশনে JavaScript-এর Memory Management — Memory Lifecycle, Garbage Collection অ্যালগরিদম, Memory Leak-এর কারণ ও প্রতিকার — বাংলায় উদাহরণসহ বিস্তারিত আলোচনা করা হয়েছে।


🔷 Memory Lifecycle — মেমোরির জীবনচক্র

JavaScript-এ Memory তিনটি ধাপে কাজ করে — Allocate (মেমোরি নেওয়া), Use (ব্যবহার করা), এবং Release (মুক্ত করা)। JavaScript Engine স্বয়ংক্রিয়ভাবে মেমোরি manage করে — Garbage Collector-এর মাধ্যমে।

ধাপ কখন হয়? উদাহরণ
১. Allocation Variable declare, Object/Array/Function তৈরি const x = 42, new Array(1000)
২. Use Variable পড়া ও লেখা x + 1, arr.push()
৩. Release Garbage Collector — reference শূন্য হলে Scope শেষ, = null

Stack ও Heap — দুই ধরনের মেমোরি Stack / Heap

// ===== Stack — Primitive Values ===== // Stack = Fixed size, দ্রুত, স্বয়ংক্রিয় release। // Primitive type সরাসরি Stack-এ। let a = 42; // Stack-এ 42 let b = a; // Stack-এ আলাদা 42 (copy) b = 100; console.log(a); // → 42 (a অপরিবর্তিত) console.log(b); // → 100 // Function call → Stack Frame: function add(x, y) { const result = x + y; // Stack-এ return result; } // function শেষে Stack Frame মুক্ত হয় // ===== Heap — Reference Values ===== // Heap = Dynamic size, object/array/function এখানে। // Variable-এ Heap-এর address (reference) থাকে। const obj1 = { name: "করিম" }; // Heap-এ Object, Stack-এ reference const obj2 = obj1; // Stack-এ একই Heap address obj2.name = "রাহেলা"; console.log(obj1.name); // → রাহেলা ⚠️ (একই Heap object!) // Deep Copy: const obj3 = { ...obj1 }; // নতুন Heap Object obj3.name = "সজল"; console.log(obj1.name); // → রাহেলা (অপরিবর্তিত ✅) // ===== Memory Allocation Examples ===== let num = 42; // ~8 bytes (Stack) let str = "হ্যালো"; // Heap-এ String let arr = [1, 2, 3]; // Heap-এ Array (~24+ bytes) let obj = { a: 1 }; // Heap-এ Object let fn = () => {}; // Heap-এ Function Object let bigArr = new Array(1000000); // ~8MB Heap!

🔷 Garbage Collection — স্বয়ংক্রিয় মেমোরি মুক্তি

Garbage Collector (GC) হলো JavaScript Engine-এর অংশ যা স্বয়ংক্রিয়ভাবে অব্যবহৃত Object-এর মেমোরি মুক্ত করে। প্রোগ্রামারকে নিজে free() call করতে হয় না।

Reference Counting — পুরানো অ্যালগরিদম Reference Counting

// Reference Counting = প্রতিটি object-এ কতটি reference আছে গোনা। // Count = 0 হলে → Garbage Collect। let user = { name: "করিম" }; // Reference count = 1 let alias = user; // Reference count = 2 user = null; // Reference count = 1 (alias এখনো আছে) alias = null; // Reference count = 0 → মুক্ত! // ===== Reference Counting-এর সমস্যা — Circular Reference ===== function makeCircular() { let obj1 = {}; let obj2 = {}; obj1.partner = obj2; // obj2-এর reference count = 1 obj2.partner = obj1; // obj1-এর reference count = 1 // obj1 ও obj2 একে অপরকে reference করছে! return "done"; } makeCircular(); // makeCircular() শেষ, কিন্তু obj1 ও obj2-এর count = 1 (circular!) // Reference Counting-এ এগুলো কখনো collect হবে না — Memory Leak! // আধুনিক Engine-এ Mark-and-Sweep এ সমস্যা নেই।

Mark-and-Sweep — আধুনিক অ্যালগরিদম Mark-and-Sweep

// Mark-and-Sweep ধাপ: // ১. Root: Global variables, Call Stack, Active closures। // ২. Root থেকে পৌঁছানো যায় এমন সব object "mark" করো। // ③ Mark নেই = Unreachable → Heap থেকে সরাও। // উদাহরণ: let root = { child: { data: [1, 2, 3], nested: { value: 42 } } }; // root → child → data (সব marked — reachable) // root → child → nested (marked) root = null; // root unreachable! // root, child, data, nested — সবই unreachable → Garbage // ===== Generational GC ===== // আধুনিক Engine-এ Generational GC: // Young Generation (Nursery) = নতুন object — ঘন ঘন collect। // Old Generation (Tenured) = টিকে যাওয়া object — কম ঘন ঘন। // Incremental ও Concurrent GC: // পুরো program না থামিয়ে ছোট ছোট করে collect। // V8 Engine-এ: Minor GC + Major GC (Full Mark-and-Sweep)

WeakRef ও FinalizationRegistry — ES2021 ES2021

// WeakRef = Garbage Collection-কে না আটকে Reference রাখা। // Strong Reference → GC আটকায়। // Weak Reference → GC আটকায় না। let heavyObject = { data: new Array(1000000) }; // WeakRef — strong reference না রেখে: const weakRef = new WeakRef(heavyObject); // heavyObject = null করলে GC collect করতে পারবে: heavyObject = null; // deref() — object এখনো আছে কিনা: const obj = weakRef.deref(); if (obj) { console.log("Object এখনো আছে"); } else { console.log("GC সরিয়ে দিয়েছে"); } // Cache-এ WeakRef: const cache = new Map(); function getOrCreate(key) { const cached = cache.get(key)?.deref(); if (cached) return cached; const newObj = { key, data: new Array(1000) }; cache.set(key, new WeakRef(newObj)); return newObj; } // ===== FinalizationRegistry ===== // Object Garbage Collected হলে callback: const registry = new FinalizationRegistry((value) => { console.log(`"${value}" collect হয়েছে — cleanup করছি`); }); let resource = { name: "database-connection" }; registry.register(resource, "database-connection"); resource = null; // GC করলে callback চলবে

🔷 Memory Leak — কারণ ও সমাধান

Memory Leak হলো এমন মেমোরি যা আর ব্যবহার হচ্ছে না, কিন্তু Reference-এর কারণে GC collect করতে পারছে না। ধীরে ধীরে Memory বাড়তে থাকে — App ধীর বা Crash করে।

Leak ১ — Accidental Global Variable Global Variable

// ❌ সমস্যা: function createData() { // var/let/const ছাড়া — Global হয়ে যায়! leakedData = new Array(1000000); // window.leakedData } createData(); // leakedData গেলে GC করবে না! // ✅ সমাধান: "use strict"; // Strict Mode-এ accidental global → Error function createDataFixed() { const localData = new Array(1000000); // Local — function শেষে মুক্ত return localData.length; }

Leak ২ — Event Listener Remove না করা Event Listener

// ❌ সমস্যা — Element সরানোর পর Listener থেকে যায়: function setup() { const button = document.querySelector("#btn"); const heavyData = new Array(100000); // Listener Closure-এ আটকা button.addEventListener("click", () => { console.log(heavyData.length); // heavyData reference }); // button DOM থেকে সরালেও Listener (ও heavyData) মেমোরিতে থাকে! } // ✅ সমাধান ১ — Named Function + removeEventListener: function handleClick() { console.log("ক্লিক"); } button.addEventListener("click", handleClick); // পরে: button.removeEventListener("click", handleClick); // ✅ সমাধান ২ — { once: true }: button.addEventListener("click", handler, { once: true }); // একবার চললেই auto-remove! // ✅ সমাধান ৩ — AbortController: const controller = new AbortController(); button.addEventListener("click", handler, { signal: controller.signal }); // সব একসাথে বন্ধ: controller.abort();

Leak ৩ — Closure-এ অপ্রয়োজনীয় Reference Closure

// ❌ সমস্যা — Closure বড় Object ধরে রাখছে: function createLeak() { const hugeData = new Array(1000000).fill("data"); // 8MB return function() { // hugeData ব্যবহার করছে না, কিন্তু Closure-এ আটকে আছে! return "ছোট ফলাফল"; }; } const leakyFn = createLeak(); // hugeData মেমোরিতে আটকা! // ✅ সমাধান — দরকারী অংশ বের করো: function createFixed() { const hugeData = new Array(1000000).fill("data"); const summary = hugeData.length; // শুধু length রাখো // hugeData এখন Closure-এ নেই: return function() { return summary; // ছোট number }; } // hugeData GC করতে পারবে

Leak ৪ — Timer ও Cache-এ Reference Timer / Cache

// ❌ setInterval বন্ধ না করলে: function startPolling() { const heavyResource = fetchHeavyData(); setInterval(() => { heavyResource.process(); // heavyResource আটকে আছে }, 1000); // clearInterval কখনো call হয় না → Leak! } // ✅ সমাধান: class Poller { #intervalId = null; start(resource) { this.#intervalId = setInterval(() => { resource.process(); }, 1000); } stop() { clearInterval(this.#intervalId); // cleanup! this.#intervalId = null; } } // ❌ Unbounded Cache — সীমাহীন বৃদ্ধি: const cache = {}; function cacheResult(key, value) { cache[key] = value; // কখনো সরানো হয় না! } // ✅ সমাধান ১ — LRU Cache (সীমিত আকার): class LRUCache { #map = new Map(); #maxSize; constructor(maxSize = 100) { this.#maxSize = maxSize; } get(key) { if (!this.#map.has(key)) return undefined; const value = this.#map.get(key); this.#map.delete(key); this.#map.set(key, value); // Recent হিসেবে শেষে রাখো return value; } set(key, value) { if (this.#map.has(key)) this.#map.delete(key); else if (this.#map.size >= this.#maxSize) { // সবচেয়ে পুরানো সরাও: this.#map.delete(this.#map.keys().next().value); } this.#map.set(key, value); } } // ✅ সমাধান ২ — WeakMap (Object key হলে): const weakCache = new WeakMap(); // Key GC হলে cache-ও সরে

🔷 দ্রুত রেফারেন্স — Memory Management

Memory Leak-এর কারণ ও সমাধান এক নজরে Summary

কারণ উদাহরণ সমাধান
Accidental Global data = [] (var ছাড়া) Strict Mode, let/const সবসময়
Event Listener না সরানো removeEventListener কখনো call হয় না Named function, once:true, AbortController
Closure-এ বড় object Closure unnecessary reference ধরছে শুধু দরকারী অংশ extract করো
setInterval বন্ধ না করা clearInterval কখনো call হয় না Cleanup function-এ clearInterval
Unbounded Cache Map/Object-এ entry কখনো সরে না LRU Cache, WeakMap, TTL সেট করো
DOM Reference — সরানো Element Detached DOM tree memory-তে থাকে Variable null করো, WeakRef ব্যবহার করো

মেমোরি দক্ষ কোড লেখার নিয়ম Best Practices

নিয়ম কারণ
সবসময় let/const ব্যবহার করো Accidental Global এড়ানো
Event Listener সবসময় cleanup করো Detached element-এর Listener থেকে যায়
বড় object আর দরকার না হলে = null Reference কেটে GC-কে সাহায্য করো
Cache-এ সীমা রাখো (LRU বা TTL) Unbounded growth এড়ানো
Object key-এর Cache-এ WeakMap ব্যবহার করো Key GC হলে Value-ও মুক্ত
Generator দিয়ে Lazy data processing পুরো data মেমোরিতে না রেখে একটু একটু
Chrome DevTools-এ মেমোরি profile করো Leak সনাক্ত করতে

🧠 নিজেকে যাচাই করো

1. Garbage collection কী?

2. Memory leak কী?

3. WeakRef কেন?

✏️ Task — এখন তুমি করো

DevTools-এর Memory tab-এ portfolio-এর heap snapshot দেখো।

ধাপ 19🏗️ Real Project — Interactive Portfolio

Memory management বুঝে efficient Portfolio বানাও।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio-এ event listener cleanup করো।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

🛠️ Using Browser DevTools — সম্পূর্ণ নোট

এই সেকশনে Chrome DevTools-এর সব গুরুত্বপূর্ণ দিক — Debugging Issues, Debugging Memory Leaks, এবং Debugging Performance — বাংলায় উদাহরণসহ বিস্তারিত আলোচনা করা হয়েছে।


🔷 Browser DevTools পরিচিতি

Browser DevTools হলো Browser-এর built-in development tool যা JavaScript debug করা, Performance analyze করা এবং Memory Leak খোঁজার জন্য ব্যবহার করা হয়। Chrome DevTools সবচেয়ে শক্তিশালী ও প্রচলিত।

Panel কাজ Shortcut
Elements DOM ও CSS inspect ও edit Ctrl+Shift+C
Console Log দেখা, JavaScript execute Ctrl+Shift+J
Sources JavaScript debug, Breakpoint Ctrl+Shift+I → Sources
Network HTTP request, response, timing Ctrl+Shift+I → Network
Performance Rendering, scripting, paint — FPS Ctrl+Shift+I → Performance
Memory Heap snapshot, Memory Leak Ctrl+Shift+I → Memory
Application localStorage, Cookie, Cache Ctrl+Shift+I → Application
Lighthouse Performance, SEO, Accessibility audit Ctrl+Shift+I → Lighthouse

🔷 Debugging Issues — Console ও Sources Panel

Console-এর সব Method Console

// ===== Basic Logging ===== console.log("সাধারণ তথ্য"); console.info("ℹ️ তথ্য বার্তা"); console.warn("⚠️ সতর্কবার্তা"); console.error("❌ Error বার্তা"); console.debug("🔍 Debug তথ্য (verbose)"); // ===== Structured Output ===== // Object/Array সুন্দরভাবে: const user = { name: "করিম", age: 25, scores: [85, 92, 78] }; console.log(user); // expandable object console.dir(user); // DOM element-এর property tree // Table: const students = [ { name: "করিম", score: 85, grade: "A+" }, { name: "রাহেলা", score: 92, grade: "A+" }, { name: "সজল", score: 78, grade: "A" }, ]; console.table(students); // সুন্দর Table দেখাবে! // Group: console.group("API Response"); console.log("Status: 200"); console.log("Data:", user); console.groupCollapsed("Headers"); // Collapsed শুরুতে console.log("Content-Type: application/json"); console.groupEnd(); console.groupEnd(); // ===== Performance ===== console.time("loop"); for (let i = 0; i < 1000000; i++) {} console.timeEnd("loop"); // → loop: 5.2ms console.count("clicked"); // ক্লিক গোনা console.count("clicked"); // → clicked: 2 console.countReset("clicked"); //=====Assert=====console.assert(1===1, "এটা কখনো দেখা যাবে না" ); console.assert(1===2, "এটা Error হিসেবে দেখাবে!" ); // → Assertion failed // Stack trace: console.trace("এখানে কীভাবে এলাম?"); // Call stack দেখায় // Clear: console.clear();

Sources Panel — Breakpoint ও Debugger Breakpoints

// ===== debugger statement ===== // Code-এ debugger লিখলে DevTools খোলা থাকলে সেখানে থামে: function calculateTotal(items) { let total = 0; for (const item of items) { debugger; // ← এখানে থামবে, DevTools-এ inspect করা যাবে total += item.price * item.qty; } return total; } // ===== Conditional Breakpoint ===== // Sources Panel-এ line number-এ Right-click → Add conditional breakpoint: // শর্ত লেখো: item.price > 1000 // শুধু দামি item-এর loop-এ থামবে // ===== Logpoint ===== // Right-click → Add logpoint: `item.name: ${item.price}` // console.log না লিখেও log দেখা যাবে! // ===== Exception Breakpoint ===== // Sources → Pause on exceptions (⏸ icon) // সব Error-এ বা শুধু uncaught Error-এ থামবে // ===== Stepping Controls ===== // F8 — Resume (পরের Breakpoint পর্যন্ত চলো) // F10 — Step over (পরের লাইনে যাও, function-এ ঢুকবে না) // F11 — Step into (function-এর ভেতরে যাও) // Shift+F11 — Step out (বর্তমান function থেকে বের হও) // ===== Watch Expressions ===== // Sources Panel → Watch → "+" দিয়ে expression যোগ: // total, item.price * item.qty, items.length // Breakpoint-এ এগুলোর মান দেখা যাবে // ===== Call Stack ===== // Breakpoint-এ থামলে Call Stack panel-এ দেখো: // কোন function কোন function থেকে call হয়েছে // ===== Live Edit ===== // Sources Panel-এ JavaScript সরাসরি edit করে Ctrl+S // Page reload ছাড়াই test করা যাবে!

Network Panel — API Debug করা Network

// Network Panel-এ কী দেখবে: // ১. Request Filter: // XHR/Fetch — API calls // JS — Script files // CSS/Img — Static assets // WS — WebSocket // ২. প্রতিটি Request-এ: // Headers tab — Request/Response headers, Status code // Preview tab — Formatted response (JSON tree) // Response tab — Raw response // Timing tab — কতক্ষণ লেগেছে breakdown-সহ // ৩. Timing Breakdown: // Queued — Request queue-এ অপেক্ষা // DNS Lookup — Domain → IP // Initial connection — TCP Handshake // SSL — HTTPS negotiation // TTFB — Time to First Byte (Server response time) // Content Download — Data transfer // ৪. Throttling — Slow network simulate: // Fast 3G, Slow 3G, Offline // Custom: 100 kbps download // ৫. Preserve Log — Page reload-এ log রাখো // ৬. Disable Cache — Dev-এ cache bypass // DevTools Console-এ Network: const response = await fetch("https://api.example.com/users"); // Network Panel-এ দেখা যাবে!

🔷 Debugging Memory Leaks — Memory Panel

Heap Snapshot — Memory Leak খোঁজা Heap Snapshot

// ===== Memory Panel-এ কাজ করার পদ্ধতি ===== // ধাপ ১: Heap Snapshot নাও // Memory Panel → Heap snapshot → Take snapshot // (Snapshot 1 — baseline) // ধাপ ২: Action করো (যা Leak সন্দেহ করছ): function possibleLeak() { const data = new Array(10000).fill({ name: "test" }); listeners.push(data); // Leak! } possibleLeak(); possibleLeak(); possibleLeak(); // ধাপ ৩: আরেকটি Snapshot নাও (Snapshot 2) // ধাপ ৪: Comparison // Dropdown → Snapshot 2 → Compare to Snapshot 1 // #New = নতুন Object-এর সংখ্যা // #Deleted = GC করা Object // #Delta = পার্থক্য (Positive = বাড়ছে → Leak?) // ধাপ ৫: Suspicious objects খোঁজো // সাধারণত: Array, closure, DOM nodes // ===== Detached DOM Trees ===== // Heap Snapshot Filter: "Detached" // DOM tree থেকে সরানো হয়েছে কিন্তু JS Reference আটকে রেখেছে: const detachedNodes = []; function createAndDetach() { const div = document.createElement("div"); document.body.appendChild(div); detachedNodes.push(div); // ← Detached Node Leak document.body.removeChild(div); // DOM থেকে সরানো হয়েছে // কিন্তু detachedNodes-এ reference আছে! } // ===== Retainer — কে ধরে রেখেছে? ===== // Heap Snapshot-এ Object ক্লিক করো // Retainers tree দেখো — কোন variable/function ধরে রেখেছে

Allocation Timeline — Real-time Memory Timeline

// Memory Panel → Allocation instrumentation on timeline → Start // কাজ করো (যা Leak সন্দেহ) → Stop // Timeline-এ দেখো: // নীল bar = নতুন allocation // ধূসর bar = GC করা (মুক্ত) // নীল bar যদি ধূসর না হয় → Leak! // ===== Sampling Memory Profiler ===== // Memory Panel → Allocation sampling → Start // কিছুক্ষণ ব্যবহার করো → Stop // কোন function সবচেয়ে বেশি memory allocate করছে দেখা যাবে // ===== Performance Monitor ===== // Three dots → More tools → Performance Monitor // JS heap size, DOM Nodes, Listeners — real-time graph // Continuously বাড়লে Leak! // ===== Console-এ Memory Info ===== console.memory; // Chrome-এ: // { // jsHeapSizeLimit: 2172649472, // Maximum // totalJSHeapSize: 25000000, // Allocated // usedJSHeapSize: 15000000, // Used // } // Leak test pattern: async function testForLeak() { const before = performance.memory?.usedJSHeapSize; // সন্দেহজনক কাজ: for (let i = 0; i < 100; i++) { possibleLeakyOperation(); } // GC force করার চেষ্টা (DevTools-এ GC button): await new Promise(r=> setTimeout(r, 100)); const after = performance.memory?.usedJSHeapSize; console.log(`Memory change: ${((after - before) / 1024 / 1024).toFixed(2)} MB`); }

🔷 Debugging Performance — Performance Panel

Performance Panel — Recording ও Analysis Performance

// Performance Panel ব্যবহার করার পদ্ধতি: // ১. Record → কিছু কাজ করো → Stop // ২. Flame Chart দেখো: // Main thread → কোন function কতক্ষণ লাগছে // গভীর stack = nested function calls // লম্বা bar = ধীর function // ৩. Summary Tab: // Scripting = JS execution time // Rendering = Layout, Style calculation // Painting = Pixel drawing // Idle = কিছু করছে না // ৪. Long Tasks: // লাল triangle = Long Task (50ms+) // User input block করে → Jank (ঝাঁকুনি) // ===== Common Performance Issues ===== // ১. Long Task — UI Block করা: // ❌ সমস্যা: function processHeavyData(data) { // এটি 500ms লাগে — UI freeze! return data.map(item => expensiveOperation(item)); } // ✅ সমাধান — Chunking: async function processHeavyDataFixed(data, chunkSize = 100) { const results = []; for (let i = 0; i < data.length; i +=chunkSize) { const chunk=data.slice(i, i + chunkSize); results.push(...chunk.map(expensiveOperation)); // Browser-কে একটু বিশ্রাম দাও: await new Promise(r=> setTimeout(r, 0)); } return results; } // ২. Web Worker — Main thread-এ ভারী কাজ না করা: // worker.js: // self.onmessage = (e) => { // const result = heavyComputation(e.data); // self.postMessage(result); // }; // main.js: const worker = new Worker("./worker.js"); worker.postMessage(largeData); worker.onmessage = (e) => console.log("ফলাফল:", e.data);

Rendering Performance — Layout Thrashing রোধ Rendering

// ===== Layout Thrashing ===== // Read ও Write মিশিয়ে করলে Browser বারবার Layout করে // ❌ Layout Thrashing: const elements = document.querySelectorAll(".box"); elements.forEach(el => { const width = el.offsetWidth; // Read → Layout force el.style.width = width * 2 + "px"; // Write // পরের iteration-এ আবার Read → আবার Layout force! }); // ✅ সমাধান — Read সব আগে, Write সব পরে: const widths = [...elements].map(el => el.offsetWidth); // সব Read elements.forEach((el, i) => { el.style.width = widths[i] * 2 + "px"; // সব Write }); // ===== requestAnimationFrame — Smooth Animation ===== // ❌ setInterval দিয়ে Animation: // setInterval(() => element.style.left = x + "px", 16); // Jank! // ✅ requestAnimationFrame: function animate(timestamp) { const progress = timestamp / 1000; element.style.transform = `translateX(${progress * 100}px)`; if (progress < 3) { requestAnimationFrame(animate); // পরের frame-এ আবার } } requestAnimationFrame(animate); // Browser-এর repaint-এর সাথে sync //=====will-change CSS hint=====// element.style.willChange="transform" ; // GPU layer-এ promote // Animate করার আগে set করো, শেষ হলে সরাও: // element.style.willChange="auto" ; //=====CSS Containment=====// .component { contain: layout style paint; } // Browser-এ এই element-এর change শুধু ভেতরে affect করে

Performance API — Code-এ Timing মাপা Performance API

// ===== performance.now() — High Resolution Timer ===== const start = performance.now(); // সময় মাপার কাজ: const result = expensiveOperation(); const end = performance.now(); console.log(`সময় লেগেছে: ${(end - start).toFixed(2)}ms`); // ===== User Timing API — Custom Marks ===== performance.mark("api-call-start"); const data = await fetch("/api/data").then(r => r.json()); performance.mark("api-call-end"); performance.measure("API Call Duration", "api-call-start", "api-call-end"); // সব measurement দেখা: const measures = performance.getEntriesByType("measure"); measures.forEach(m => { console.log(`${m.name}: ${m.duration.toFixed(2)}ms`); }); // Performance Panel-এ User Timing-ও দেখা যাবে! // ===== PerformanceObserver ===== const observer = new PerformanceObserver((list) => { for (const entry of list.getEntries()) { if (entry.duration > 50) { // Long Task console.warn(`Long Task detected: ${entry.duration.toFixed(0)}ms`); } } }); observer.observe({ type: "longtask" }); observer.observe({ type: "largest-contentful-paint" }); observer.observe({ type: "first-input" }); // Core Web Vitals: // LCP (Largest Contentful Paint) < 2.5s — Loading // FID (First Input Delay) < 100ms — Interactivity // CLS (Cumulative Layout Shift) < 0.1 — Stability

🔷 দ্রুত রেফারেন্স — Browser DevTools

Debugging Workflow Workflow

সমস্যা Panel পদ্ধতি
JavaScript Error Console Error message পড়ো, Stack trace অনুসরণ করো
Logic Bug Sources Breakpoint, Step through, Watch variable
API সমস্যা Network Request/Response headers, Status code, Body দেখো
Memory Leak Memory Heap Snapshot নাও, Compare করো, Detached DOM খোঁজো
Page ধীর Performance Record করো, Long Task খোঁজো, Flame Chart দেখো
Layout Jank Performance + Rendering FPS meter, Layout Shift, Paint Flashing
localStorage/Cookie Application Storage দেখো, edit করো, clear করো

দরকারী Keyboard Shortcuts Shortcuts

Shortcut কাজ
F12 বা Ctrl+Shift+I DevTools খোলা/বন্ধ
Ctrl+Shift+J Console খোলা
Ctrl+Shift+C Element Inspector
Ctrl+P (Sources-এ) File খোঁজা
Ctrl+G (Sources-এ) Line number-এ যাও
F8 Resume (Breakpoint থেকে)
F10 Step over
F11 Step into
Shift+F11 Step out
Ctrl+L Console clear
Esc Console drawer toggle

🧠 নিজেকে যাচাই করো

1. Console tab কী কাজে?

2. Network tab কী দেখায়?

3. Breakpoint কী?

✏️ Task — এখন তুমি করো

DevTools-এ portfolio-এর CSS live edit করো। Network-এ request দেখো।

ধাপ 20🏗️ Real Project — Interactive Portfolio

DevTools দিয়ে Portfolio debug করতে শেখো।

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

Portfolio-এর performance DevTools-এ check করো।

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!

📖 JavaScript Quick Reference — সম্পূর্ণ JS রেফারেন্স

JavaScript-এর সব গুরুত্বপূর্ণ Concept, Method, ব্যবহার এবং সংক্ষিপ্ত উদাহরণ — এক জায়গায়।


🔷 Data Types ও Variable — ডেটা টাইপ ও ভেরিয়েবল

Keyword / Type সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
var Function-scoped variable (পুরনো) Hoisting সহ — এড়িয়ে চলা ভালো var name = "Farid";
let Block-scoped পরিবর্তনযোগ্য variable Loop counter, reassignable value let count = 0;
const Block-scoped পরিবর্তনঅযোগ্য binding Object, Array, fixed value-এ const PI = 3.14159;
Number সংখ্যা টাইপ — integer ও float গণনা, মূল্য, পরিমাপ let price = 99.5;
String লেখার ডেটা টাইপ নাম, বার্তা, URL let msg = "হ্যালো!";
Boolean সত্য বা মিথ্যা মান Condition, Flag, Toggle let isActive = true;
null ইচ্ছাকৃতভাবে কোনো মান নেই খালি / অনুপস্থিত মান বোঝাতে let data = null;
undefined মান দেওয়া হয়নি Uninitialized variable let x; // undefined
Symbol অনন্য ও অপরিবর্তনীয় Primitive Object key, Unique identifier const id = Symbol("id");
BigInt অনেক বড় Integer — n দিয়ে শেষ Number এর সীমার বাইরে বড় সংখ্যা const big = 9007199254740993n;
Object Key-value pair-এর সংগ্রহ ডেটা মডেল, Configuration let user = { name: "Farid" };
Array তালিকা আকারের ডেটা List, Collection, Queue let nums = [1, 2, 3];
typeof Variable-এর টাইপ জানার Operator Type Checking typeof "hello" // "string"
instanceof নির্দিষ্ট Class-এর instance কিনা Type guard, Class check [] instanceof Array // true
Template Literal Backtick-এ string interpolation Dynamic string তৈরি `হ্যালো, ${name}!`
Number() মান কে Number-এ রূপান্তর String → Number Number("3.14") // 3.14
String() মান কে String-এ রূপান্তর Number → String String(100) // "100"
Boolean() মান কে Boolean-এ রূপান্তর Falsy / Truthy check Boolean(0) // false
parseInt() String থেকে Integer বের করা Form input, URL param parseInt("42px") // 42
parseFloat() String থেকে Float বের করা Price, Measurement parseFloat("3.14kg") // 3.14

🔷 Operators — অপারেটর

Operator সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
+ - * / % গাণিতিক অপারেটর যোগ, বিয়োগ, গুণ, ভাগ, ভাগশেষ 10 % 3 // 1
** Exponentiation — ঘাত শক্তির হিসাব 2 ** 10 // 1024
++ -- Increment / Decrement Loop counter বাড়ানো / কমানো let i = 0; i++; // 1
= += -= *= /= Assignment ও Compound Assignment মান সংরক্ষণ ও আপডেট x += 5;
== != Loose Equality — টাইপ নির্বিশেষে এড়িয়ে চলা ভালো — === ব্যবহার করুন "5" == 5 // true
=== !== Strict Equality — মান ও টাইপ উভয় সব Comparison-এ এটি ব্যবহার করুন "5" === 5 // false
< > <= >= তুলনামূলক অপারেটর Sorting, Condition age >= 18
&& Logical AND — উভয় সত্য হলে Multiple condition isLoggedIn && isAdmin
|| Logical OR — যেকোনো একটি সত্য হলে Default value, Fallback name || "Anonymous"
! Logical NOT — উল্টো Boolean Boolean flip !isActive
?? Nullish Coalescing — null / undefined হলে || এর নিরাপদ বিকল্প user.name ?? "Guest"
?. Optional Chaining — নিরাপদ property access Nested object-এ error এড়ানো user?.address?.city
? : Ternary Operator — এক লাইনে if-else Short conditional expression age >= 18 ? "Adult" : "Minor"
??= ||= &&= Logical Assignment Operators Conditional assignment shorthand a ??= "default";
in Object-এ property আছে কিনা Property existence check "name" in user // true
delete Object-এর property মুছে ফেলা Dynamic property removal delete user.age;
spread ... Array / Object ছড়িয়ে দেওয়া Clone, Merge, Pass args [...arr1, ...arr2]
typeof টাইপ জানার Operator Runtime type check typeof null // "object"
void Expression evaluate করে undefined ফেরায় Anchor href-এ JS call void 0 // undefined

🔷 Control Flow — নিয়ন্ত্রণ প্রবাহ

Statement সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
if / else if / else শর্তভিত্তিক কোড চালানো সবচেয়ে সাধারণ Branching if (x > 0) { } else { }
switch / case / default একাধিক নির্দিষ্ট মানে Branching Menu, State Machine switch(color) { case "red": break; }
for নির্দিষ্ট সংখ্যকবার Loop Index-ভিত্তিক Iteration for (let i = 0; i < 5; i++) { }
while শর্ত সত্য থাকলে Loop অজানা সংখ্যক Iteration while (queue.length > 0) { }
do...while একবার চালিয়ে তারপর শর্ত চেক অন্তত একবার চালানো দরকার do { attempt(); } while (!done);
for...of Iterable-এর প্রতিটি মান Array, String, Set-এ Loop for (const item of items) { }
for...in Object-এর প্রতিটি key Object Property-তে Loop for (const key in obj) { }
break Loop বা Switch থেকে বের হওয়া Early exit if (found) break;
continue বর্তমান Iteration বাদ দিয়ে পরেরটিতে Skip করা if (x % 2 === 0) continue;
return Function থেকে মান ফেরানো ও থামানো সব ধরনের Function return result;
throw ইচ্ছাকৃতভাবে Error ছুঁড়ে দেওয়া Validation, Custom Error throw new Error("Invalid input");
try / catch / finally Error ধরা ও সামলানো API call, JSON parse try { } catch(e) { } finally { }
Labeled Statement Named Loop — break/continue করতে Nested Loop থেকে বের হওয়া outer: for(...) { break outer; }

🔷 Function — ফাংশন

Concept সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
Function Declaration নামসহ Function সংজ্ঞায়ন — hoisted Utility, reusable function function greet(name) { return `হ্যালো ${name}`; }
Function Expression Variable-এ Function সংরক্ষণ Callback, Conditional define const add = function(a, b) { return a + b; };
Arrow Function সংক্ষিপ্ত Function syntax — নিজস্ব this নেই Callback, Array method const double = x => x * 2;
Default Parameter Argument না দিলে ডিফল্ট মান Optional argument function greet(name = "বন্ধু") { }
Rest Parameter বাকি সব Argument Array হিসেবে Variable arguments function sum(...nums) { return nums.reduce((a,b) => a+b, 0); }
IIFE তাৎক্ষণিক Function কল Scope isolate, Module pattern (function() { })();
Closure Function তার outer scope মনে রাখে Private state, Factory function function counter() { let n=0; return ()=>++n; }
Higher-Order Function Function নেয় বা ফেরায় এমন Function map, filter, reduce, compose const apply = (fn, x) => fn(x);
Callback অন্য Function-কে argument হিসেবে দেওয়া Event handler, Async arr.forEach(item => console.log(item));
Recursion Function নিজেকে নিজে ডাকে Tree traversal, Factorial function fact(n) { return n <= 1 ? 1 : n * fact(n-1); }
call() নির্দিষ্ট this দিয়ে Function call this binding override greet.call(obj, "Farid");
apply() Array argument দিয়ে Function call Math.max-এ Array pass Math.max.apply(null, nums);
bind() নির্দিষ্ট this বাঁধা নতুন Function Event listener-এ this ঠিক রাখা const bound = greet.bind(obj);
Currying Multi-arg function-কে একের পর এক call Partial application, Composition const add = a => b => a + b;
Generator Function function* — pause ও resume করা যায় Lazy evaluation, Iterator function* gen() { yield 1; yield 2; }

🔷 Array Methods — অ্যারে পদ্ধতি

Method সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
.push() শেষে element যোগ করা Stack, Queue তৈরিতে arr.push(4);
.pop() শেষ element বের করা Stack থেকে বের করা arr.pop();
.shift() প্রথম element বের করা Queue থেকে বের করা arr.shift();
.unshift() শুরুতে element যোগ করা Priority insert arr.unshift(0);
.splice() নির্দিষ্ট index-এ যোগ / বাদ দেওয়া List থেকে item মুছতে বা ঢোকাতে arr.splice(1, 1, "x");
.slice() Array-র অংশ নেওয়া — মূল পরিবর্তন হয় না Pagination, Subarray arr.slice(1, 3);
.concat() দুটি Array জুড়ে নতুন Array Array merge arr1.concat(arr2);
.indexOf() প্রথম মিলের index বের করা Element খোঁজা arr.indexOf("a"); // 0
.includes() মান আছে কিনা — Boolean Membership check arr.includes(3); // true
.find() শর্ত মেটা প্রথম element Object Array-তে search arr.find(x => x.id === 5);
.findIndex() শর্ত মেটা প্রথম element-এর index Position জানতে arr.findIndex(x => x > 10);
.filter() শর্ত মেটা সব element নিয়ে নতুন Array Search, Category filter arr.filter(x => x > 0);
.map() প্রতিটি element রূপান্তর করে নতুন Array Data transform, Render list arr.map(x => x * 2);
.reduce() সব element দিয়ে একটি মান বের করা Sum, Group, Flatten arr.reduce((acc, x) => acc + x, 0);
.forEach() প্রতিটি element-এ Function চালানো Side effect — DOM update arr.forEach(item => console.log(item));
.some() যেকোনো একটি element শর্ত মেটায় কিনা hasAdult, hasError arr.some(x => x < 0);
.every() সব element শর্ত মেটায় কিনা Validation, allValid arr.every(x => x > 0);
.flat() Nested Array সমতল করা 2D → 1D array [[1,2],[3]].flat(); // [1,2,3]
.flatMap() map + flat একসাথে Transform ও flatten arr.flatMap(x => [x, x*2]);
.sort() Array সাজানো — মূল Array পরিবর্তন হয় Alphabetical, Numeric sort arr.sort((a,b) => a - b);
.reverse() Array উল্টানো Descending order arr.reverse();
.join() Array → String রূপান্তর CSV, Path তৈরি arr.join(", ");
.fill() নির্দিষ্ট মান দিয়ে পূরণ করা Array initialize new Array(5).fill(0);
.at() index দিয়ে element নেওয়া — negative সমর্থিত শেষ element: arr.at(-1) arr.at(-1);
Array.from() Iterable বা Array-like → Array NodeList, Set → Array Array.from("abc"); // ["a","b","c"]
Array.isArray() Array কিনা চেক Type guard Array.isArray([]); // true
.toSorted() নতুন Sorted Array — মূল অপরিবর্তিত Immutable sort arr.toSorted((a,b) => a-b);
.toReversed() নতুন Reversed Array — মূল অপরিবর্তিত Immutable reverse arr.toReversed();
.with() নির্দিষ্ট index-এ মান বদলে নতুন Array Immutable update arr.with(2, 99);

🔷 Object Methods — অবজেক্ট পদ্ধতি

Method / Concept সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
Object.keys() Object-এর সব key-এর Array Property list করা Object.keys(user); // ["name","age"]
Object.values() Object-এর সব value-এর Array Value-এ iterate করা Object.values(user);
Object.entries() [key, value] pair-এর Array Map করা, transform করা Object.entries(user);
Object.assign() Object merge বা clone করা Shallow copy, Config merge Object.assign({}, defaults, opts);
Object.freeze() Object পরিবর্তন রোধ করা Immutable config, Constant Object.freeze(config);
Object.seal() নতুন property যোগ রোধ — মান পরিবর্তন সম্ভব Shape নির্দিষ্ট রাখা Object.seal(user);
Object.create() নির্দিষ্ট Prototype থেকে Object তৈরি Prototype chain তৈরি Object.create(proto);
Object.fromEntries() [key, value] Array → Object Map → Object, entries reverse Object.fromEntries([["a",1]]);
Object.hasOwn() নিজস্ব property আছে কিনা hasOwnProperty-র আধুনিক বিকল্প Object.hasOwn(obj, "name");
Object.defineProperty() Property-র Descriptor সহ সংজ্ঞায়ন Getter / Setter, Non-enumerable Object.defineProperty(obj, "x", { get() { } });
Getter / Setter Property-র মতো কাজ করে Function Computed property, Validation get fullName() { return `${this.first} ${this.last}`; }
Shorthand Property Variable নাম = Key হলে সংক্ষিপ্ত Object literal const obj = { name, age };
Computed Property Dynamic key দিয়ে Object তৈরি Dynamic key name const obj = { [key]: "মান" };
Spread in Object Object ছড়িয়ে merge বা clone Immutable update pattern const updated = { ...user, age: 25 };
structuredClone() Deep clone করা — built-in Nested object copy const clone = structuredClone(original);

🔷 String Methods — স্ট্রিং পদ্ধতি

Method সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
.length String-এর দৈর্ঘ্য Validation, Counter "hello".length; // 5
.toUpperCase() সব বড় হাতে রূপান্তর Header, Label "hello".toUpperCase(); // "HELLO"
.toLowerCase() সব ছোট হাতে রূপান্তর Case-insensitive compare "HELLO".toLowerCase();
.trim() উভয় পাশের whitespace সরানো Form input clean করা " hi ".trim(); // "hi"
.trimStart() / .trimEnd() শুরু বা শেষের whitespace সরানো One-sided trim " hi".trimStart();
.includes() Substring আছে কিনা Search check "hello world".includes("world");
.startsWith() নির্দিষ্ট string দিয়ে শুরু কিনা Protocol check, Prefix "https://".startsWith("https");
.endsWith() নির্দিষ্ট string দিয়ে শেষ কিনা Extension check "file.js".endsWith(".js");
.indexOf() Substring-এর প্রথম index Position খোঁজা "hello".indexOf("l"); // 2
.slice() নির্দিষ্ট অংশ বের করা Substring, Truncate "hello".slice(1, 3); // "el"
.at() index দিয়ে character — negative সমর্থিত শেষ character: str.at(-1) "hello".at(-1); // "o"
.replace() প্রথম মিল পরিবর্তন করা Text substitution "hi hi".replace("hi","হ্যালো");
.replaceAll() সব মিল পরিবর্তন করা Global replacement "a a a".replaceAll("a","b");
.split() String → Array ভাগ করা CSV parse, Word split "a,b,c".split(","); // ["a","b","c"]
.repeat() String নির্দিষ্টবার পুনরাবৃত্তি Separator, Pattern "ha".repeat(3); // "hahaha"
.padStart() শুরুতে character যোগ করে দৈর্ঘ্য পূরণ Number formatting: "007" "5".padStart(3, "0"); // "005"
.padEnd() শেষে character যোগ করে দৈর্ঘ্য পূরণ Table column align "hi".padEnd(5, ".");
.match() RegExp match বের করা Pattern search "abc123".match(/\d+/); // ["123"]
.search() RegExp-এর প্রথম match-এর index Pattern position খোঁজা "hello123".search(/\d/);
String.fromCharCode() Unicode code থেকে Character তৈরি Encoding, ASCII char String.fromCharCode(65); // "A"

🔷 Number ও Math — সংখ্যা ও গণিত

Method / Property সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
Number.isInteger() Integer কিনা চেক Validation Number.isInteger(4.0); // true
Number.isFinite() Finite সংখ্যা কিনা Infinity রোধ করতে Number.isFinite(Infinity); // false
Number.isNaN() NaN কিনা — strict check NaN check Number.isNaN(NaN); // true
.toFixed() দশমিক স্থান নির্দিষ্ট করে String Price format (3.14159).toFixed(2); // "3.14"
.toString(radix) নির্দিষ্ট base-এ String Binary, Hex convert (255).toString(16); // "ff"
Number.MAX_SAFE_INTEGER নিরাপদ সর্বোচ্চ Integer Large number check Number.MAX_SAFE_INTEGER; // 2^53-1
Math.round() নিকটতম Integer-এ গোলাকার Rating, Score round Math.round(4.5); // 5
Math.floor() নিচে গোলাকার Index, Page number Math.floor(4.9); // 4
Math.ceil() উপরে গোলাকার Pagination, Minimum charge Math.ceil(4.1); // 5
Math.abs() পরম মান — ধনাত্মক Distance, Difference Math.abs(-5); // 5
Math.max() / Math.min() সর্বোচ্চ / সর্বনিম্ন মান Highest score, Lowest price Math.max(1, 5, 3); // 5
Math.pow() ঘাত গণনা Area, Physics Math.pow(2, 10); // 1024
Math.sqrt() বর্গমূল Geometry, Distance Math.sqrt(16); // 4
Math.random() 0–1 এর মধ্যে random সংখ্যা Random item, OTP, ID Math.floor(Math.random() * 10);
Math.trunc() দশমিক অংশ বাদ দেওয়া Integer part only Math.trunc(-4.9); // -4
Math.sign() ধনাত্মক (1), শূন্য (0), ঋণাত্মক (-1) Direction check Math.sign(-5); // -1
Math.hypot() Hypotenuse — বর্গমূলের যোগফল 2D Distance calculation Math.hypot(3, 4); // 5
Math.PI π = 3.14159... Circle calculation Math.PI * r * r
Math.sin() / .cos() / .tan() Trigonometric functions Animation, Canvas, SVG Math.sin(Math.PI / 2); // 1
Math.log2() / Math.log10() Logarithm Algorithm, Scale Math.log2(8); // 3

🔷 Date ও Time — তারিখ ও সময়

Method সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
new Date() বর্তমান তারিখ ও সময় Timestamp তৈরি const now = new Date();
new Date(string) String থেকে Date Input parse new Date("2024-01-15");
Date.now() Unix Timestamp milliseconds Performance measure, ID Date.now(); // 1700000000000
.getFullYear() বছর বের করা Year display now.getFullYear(); // 2024
.getMonth() মাস বের করা — 0-indexed Month display (+1 করুন) now.getMonth(); // 0 = January
.getDate() দিন বের করা (1–31) Day display now.getDate();
.getDay() সপ্তাহের দিন — 0 = Sunday Weekday display now.getDay(); // 0 = রোববার
.getHours() / .getMinutes() / .getSeconds() ঘণ্টা, মিনিট, সেকেন্ড Clock, Timer now.getHours();
.getTime() Timestamp milliseconds Duration calculation now.getTime();
.toISOString() ISO 8601 format String API, Database now.toISOString();
.toLocaleDateString() Locale অনুযায়ী তারিখ String UI Display now.toLocaleDateString("bn-BD");
.toLocaleTimeString() Locale অনুযায়ী সময় String Clock Display now.toLocaleTimeString("bn-BD");
Intl.DateTimeFormat আধুনিক Date Formatting Localized, Custom format new Intl.DateTimeFormat("bn", { dateStyle:"long" }).format(now);
Intl.RelativeTimeFormat Relative time — "৩ দিন আগে" Social media timestamp new Intl.RelativeTimeFormat("bn").format(-3, "day");

🔷 Destructuring ও Spread — আধুনিক Syntax

Concept সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
Array Destructuring Array থেকে Variable-এ মান নেওয়া useState, Coordinate const [x, y] = [10, 20];
Object Destructuring Object থেকে Property বের করা Props, API response const { name, age } = user;
Default in Destructuring মান না থাকলে ডিফল্ট Optional property const { name = "Guest" } = user;
Rename in Destructuring ভিন্ন নামে Variable Name conflict এড়ানো const { name: userName } = user;
Nested Destructuring ভেতরের Object / Array বের করা Nested API response const { address: { city } } = user;
Rest in Destructuring বাকি সব একটি Variable-এ Exclude property, Clone const { id, ...rest } = user;
Spread in Array Array উপাদান ছড়িয়ে দেওয়া Clone, Merge, Pass args [...arr1, ...arr2]
Spread in Object Object property ছড়িয়ে দেওয়া Shallow clone, Merge { ...obj1, ...obj2 }
Variable Swap Destructuring দিয়ে swap Temp variable ছাড়া swap [a, b] = [b, a];
Parameter Destructuring Function argument হিসেবে destructure Named parameter pattern function show({ name, age }) { }

🔷 Class ও OOP — অবজেক্ট-ভিত্তিক প্রোগ্রামিং

Concept সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
class Blueprint থেকে Object তৈরির ছাঁচ Data model, Component class User { constructor(name) { this.name = name; } }
constructor() Object তৈরির সময় চালানো Method Initial property সেট constructor(name) { this.name = name; }
new Class থেকে Object (instance) তৈরি Object instantiation const user = new User("Farid");
this বর্তমান Object-এর reference Property ও Method access this.name = name;
static Class-এর নিজস্ব Method / Property Utility, Factory method static create(name) { return new User(name); }
extends Parent Class থেকে inherit করা Subclass, Specialization class Admin extends User { }
super() Parent Constructor ডাকা extends ব্যবহারে অবশ্যই super(name);
super.method() Parent-এর Method ডাকা Method override-এ Parent call super.greet();
Private Field # Class-এর বাইরে access করা যায় না Encapsulation #password = "secret";
Getter / Setter Property-র মতো Function Computed value, Validation get fullName() { return `${this.first} ${this.last}`; }
Prototype Object-এর shared Method store Memory efficient method sharing User.prototype.greet = function() { };
instanceof Instance check করা Type guard user instanceof User; // true

🔷 Error Handling — ত্রুটি সামলানো

Concept / Type সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
try...catch Error ধরা ও সামলানো API call, JSON.parse try { JSON.parse(x); } catch(e) { console.error(e); }
finally Error হোক বা না হোক চলবে Cleanup, Loading state off finally { setLoading(false); }
throw ইচ্ছাকৃত Error ছোঁড়া Custom validation error throw new Error("মান সঠিক নয়");
Error সাধারণ Error object Generic error new Error("কিছু ভুল হয়েছে");
TypeError ভুল টাইপে operation null-এ method call null.toString() // TypeError
RangeError মান বৈধ সীমার বাইরে Array(-1) ইত্যাদি new Array(-1) // RangeError
ReferenceError অঘোষিত Variable ব্যবহার Typo, Scope issue console.log(undeclaredVar)
SyntaxError ভুল JavaScript Syntax Parse time error JSON.parse("{bad}") // SyntaxError
error.message Error-এর বার্তা User-facing error message e.message;
error.stack Error-এর Call Stack Debugging e.stack;
Custom Error Class নিজস্ব Error type তৈরি Domain-specific error class ValidationError extends Error { }

🔷 Promise ও Async/Await — অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং

Concept / Method সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
new Promise() ভবিষ্যতের মান — pending / fulfilled / rejected Async operation wrap new Promise((resolve, reject) => { });
resolve() Promise সফল করা Success result পাঠানো resolve(data);
reject() Promise ব্যর্থ করা Error পাঠানো reject(new Error("Failed"));
.then() Promise সফল হলে চালানো Chaining, Data transform fetch(url).then(res => res.json());
.catch() Promise ব্যর্থ হলে চালানো Error handling .catch(err => console.error(err));
.finally() যেকোনো ক্ষেত্রে চালানো Cleanup, Loading off .finally(() => setLoading(false));
Promise.all() সব Promise শেষ হলে result Parallel API calls await Promise.all([p1, p2, p3]);
Promise.allSettled() সব Promise-এর result — সফল বা ব্যর্থ Partial success চাইলে await Promise.allSettled([p1, p2]);
Promise.race() প্রথম শেষ হওয়া Promise-এর result Timeout, Fastest response await Promise.race([fetchData(), timeout]);
Promise.any() প্রথম সফল Promise-এর result Multiple fallback source await Promise.any([p1, p2]);
async function সবসময় Promise ফেরানো Function Async logic সহজে লেখা async function getData() { }
await Promise শেষ হওয়া পর্যন্ত অপেক্ষা Sequential async operation const data = await fetch(url);
setTimeout() নির্দিষ্ট সময় পরে চালানো Delay, Debounce setTimeout(() => { }, 1000);
setInterval() নির্দিষ্ট বিরতিতে বারবার চালানো Clock, Polling const id = setInterval(() => { }, 1000);
clearTimeout() / clearInterval() Timer বন্ধ করা Cleanup on unmount clearInterval(id);

🔷 DOM Manipulation — ডকুমেন্ট নিয়ন্ত্রণ

Method / Property সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
document.querySelector() CSS Selector দিয়ে প্রথম element Element নির্বাচন document.querySelector(".btn");
document.querySelectorAll() CSS Selector দিয়ে সব element — NodeList Multiple element document.querySelectorAll("li");
document.getElementById() ID দিয়ে element খোঁজা Specific element document.getElementById("header");
document.createElement() নতুন HTML element তৈরি Dynamic element add document.createElement("div");
.appendChild() Child element শেষে যোগ করা DOM-এ element যোগ parent.appendChild(child);
.append() String বা Node শেষে যোগ Multiple node / text একসাথে el.append("text", node);
.prepend() শুরুতে Node যোগ First child insert el.prepend(newNode);
.remove() Element নিজেকে সরানো Self-remove el.remove();
.cloneNode() Element কপি করা Template duplicate el.cloneNode(true);
.innerHTML Element-এর HTML content Dynamic HTML — XSS সতর্কতা el.innerHTML = "<b>Bold</b>";
.textContent Element-এর text content — নিরাপদ Text update — XSS নেই el.textContent = "হ্যালো";
.setAttribute() Attribute সেট করা href, src, data-* সেট el.setAttribute("href", "/about");
.getAttribute() Attribute-এর মান পড়া data-* পড়া el.getAttribute("data-id");
.removeAttribute() Attribute সরানো disabled, hidden সরানো el.removeAttribute("disabled");
.classList.add() CSS class যোগ State পরিবর্তন el.classList.add("active");
.classList.remove() CSS class সরানো State সরানো el.classList.remove("hidden");
.classList.toggle() CSS class যোগ বা সরানো Toggle menu, Dark mode el.classList.toggle("open");
.classList.contains() Class আছে কিনা State check el.classList.contains("active");
.style Inline CSS সেট করা Dynamic style el.style.color = "blue";
getComputedStyle() প্রযোজ্য সব CSS পড়া Computed value জানতে getComputedStyle(el).fontSize;
.getBoundingClientRect() Element-এর position ও আকার Drag, Tooltip position el.getBoundingClientRect();
.scrollIntoView() Element দৃশ্যমান করা Smooth scroll to section el.scrollIntoView({ behavior: "smooth" });
.dataset data-* attribute সহজে read / write data-id, data-type el.dataset.userId;
.insertAdjacentHTML() নির্দিষ্ট অবস্থানে HTML insert Before / after element el.insertAdjacentHTML("afterend", "<p>...</p>");

🔷 Events — ইভেন্ট

Method / Event সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
addEventListener() Event Listener যোগ করা Click, Input, Scroll btn.addEventListener("click", handler);
removeEventListener() Event Listener সরানো Cleanup, One-time event btn.removeEventListener("click", handler);
event.preventDefault() Default Browser action রোধ Form submit, Link navigate e.preventDefault();
event.stopPropagation() Event bubble রোধ Parent-এ event না যেতে e.stopPropagation();
event.target Event ঘটানো element Event delegation e.target.classList.add("clicked");
event.key Keyboard key-এর মান KeyDown, Hotkey if (e.key === "Enter") { }
dispatchEvent() Custom Event ছোঁড়া Component communication el.dispatchEvent(new CustomEvent("done"));
Event Delegation Parent-এ Listener রেখে Child handle Dynamic list item ul.addEventListener("click", e => { if(e.target.matches("li")) { } });
click / dblclick Mouse click event Button, Card btn.addEventListener("click", fn);
mouseover / mouseout Mouse প্রবেশ ও বের হওয়া Hover effect JS-এ el.addEventListener("mouseover", fn);
keydown / keyup Keyboard event Shortcut, Form validation document.addEventListener("keydown", fn);
input / change Input মান পরিবর্তন Live search, Form state input.addEventListener("input", fn);
submit Form submit event Form handling form.addEventListener("submit", fn);
focus / blur Input Focus পাওয়া ও হারানো Validation feedback input.addEventListener("blur", fn);
scroll Scroll করা Sticky header, Infinite scroll window.addEventListener("scroll", fn);
resize Window আকার পরিবর্তন Responsive logic window.addEventListener("resize", fn);
DOMContentLoaded DOM লোড সম্পন্ন Init code চালানো document.addEventListener("DOMContentLoaded", fn);
IntersectionObserver Element Viewport-এ এলে callback Lazy load, Scroll animation new IntersectionObserver(cb).observe(el);
MutationObserver DOM পরিবর্তন পর্যবেক্ষণ Dynamic content watch new MutationObserver(cb).observe(el, { childList: true });
ResizeObserver Element আকার পরিবর্তন পর্যবেক্ষণ Container query JS-এ new ResizeObserver(cb).observe(el);

🔷 Fetch ও API — নেটওয়ার্ক অনুরোধ

Method / Property সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
fetch(url) HTTP Request পাঠানো — Promise ফেরায় GET request fetch("https://api.example.com/data");
fetch(url, options) Method, Header, Body সহ Request POST, PUT, DELETE fetch(url, { method: "POST", body: JSON.stringify(data) });
response.ok Status 200–299 কিনা Success check if (!res.ok) throw new Error();
response.status HTTP Status Code 404, 500 চেক res.status; // 200
response.json() Response → JSON parse করা REST API data পড়া const data = await res.json();
response.text() Response → String HTML, Plain text const html = await res.text();
response.blob() Response → Binary data File, Image download const blob = await res.blob();
AbortController Fetch request বাতিল করা Timeout, Component unmount const ctrl = new AbortController(); fetch(url, { signal: ctrl.signal });
ctrl.abort() Request বন্ধ করা Cancel on unmount ctrl.abort();
URL URL parse ও তৈরি Query param handle new URL("https://example.com?q=hello");
URLSearchParams Query String build / parse Search param new URLSearchParams({ q: "js" }).toString();
FormData Form data multipart তৈরি File upload const fd = new FormData(); fd.append("file", file);

🔷 localStorage ও Storage — ডেটা সংরক্ষণ

Method / API সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
localStorage.setItem() Key-value সংরক্ষণ — String User preference, Theme localStorage.setItem("theme", "dark");
localStorage.getItem() Key দিয়ে মান পড়া Stored value retrieve localStorage.getItem("theme");
localStorage.removeItem() নির্দিষ্ট key মুছে ফেলা Logout, Clear preference localStorage.removeItem("token");
localStorage.clear() সব localStorage মুছে ফেলা Full reset localStorage.clear();
sessionStorage Session শেষে মুছে যায় Tab-specific temp data sessionStorage.setItem("step", "2");
JSON.stringify() Object → JSON String Object storage-এ save করতে localStorage.setItem("user", JSON.stringify(user));
JSON.parse() JSON String → Object Storage থেকে Object পড়তে JSON.parse(localStorage.getItem("user"));
Cookie Browser-এ ছোট ডেটা — Server-ও পড়তে পারে Auth token, Session document.cookie = "name=Farid; path=/";
IndexedDB Browser-এ বড় Structured data store Offline app, Large dataset indexedDB.open("myDB", 1);
navigator.clipboard Clipboard read / write Copy to clipboard navigator.clipboard.writeText("Copied!");

🔷 Regular Expression — রেগুলার এক্সপ্রেশন

Pattern / Method সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
/pattern/flags Regex Literal তৈরি Pattern matching /hello/i.test("Hello"); // true
new RegExp() Dynamic Regex তৈরি Variable দিয়ে pattern new RegExp(word, "gi");
g flag Global — সব match replaceAll, matchAll /cat/g
i flag Case-insensitive Search ignore case /hello/i
m flag Multiline — ^ ও $ প্রতি লাইনে Multiline text /^start/m
. যেকোনো character — newline ছাড়া Wildcard /h.llo/
^ $ String-এর শুরু ও শেষ Start / End validation /^https/ /\.js$/
* + ? 0+, 1+, 0 বা 1 — repetition Optional, Required, One repetition /\d+/ /colou?r/
{n} {n,m} নির্দিষ্ট সংখ্যক repetition Phone, OTP validation /\d{4,6}/
[abc] [^abc] Character Class ও নেগেশন Vowel, Exclude characters /[aeiou]/ /[^0-9]/
\d \w \s Digit, Word char, Whitespace Number, Username, Space validation /^\d+$/ /^\w+$/
(group) Capture Group Extract match part /(\d{4})-(\d{2})/
(?<name>) Named Capture Group Named extraction /(?<year>\d{4})/
regex.test() Pattern match আছে কিনা Validation /^\d+$/.test("123"); // true
regex.exec() Match বের করা বিস্তারিত Capture group extract /(\d+)/.exec("abc123");
Lookahead (?=) পরে নির্দিষ্ট pattern থাকলে Password validation /\d(?=[a-z])/

🔷 Map, Set, WeakMap — বিশেষ Collection

Method / Property সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
new Map() Key-value store — যেকোনো Key টাইপ Object-এর শক্তিশালী বিকল্প const map = new Map();
map.set(key, val) Key-value যোগ করা Data store map.set("name", "Farid");
map.get(key) Key দিয়ে মান পড়া Lookup map.get("name"); // "Farid"
map.has(key) Key আছে কিনা Existence check map.has("age"); // false
map.delete(key) Key-value মুছে ফেলা Remove entry map.delete("name");
map.size Map-এর entry সংখ্যা Count entries map.size;
for...of map Map Iterate করা Loop through Map for (const [k,v] of map) { }
new Set() অনন্য মানের Collection Duplicate সরানো const set = new Set([1,2,2,3]);
set.add(val) মান যোগ করা — duplicate এড়ায় Unique list তৈরি set.add(4);
set.has(val) মান আছে কিনা O(1) lookup set.has(2); // true
set.delete(val) মান মুছে ফেলা Remove element set.delete(1);
Array থেকে Unique Set দিয়ে Duplicate সরানো Deduplicate [...new Set(arr)];
new WeakMap() Object Key-only Map — GC-friendly Private data, Cache const wm = new WeakMap();
new WeakSet() Object-only Set — GC-friendly Visited object track const ws = new WeakSet();

🔷 Modules (ES6) — মডিউল সিস্টেম

Syntax সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
export Module থেকে export করা Function, Class, Variable share export function greet() { }
export default Default export — একটি মাত্র Main export, Component export default class App { }
export { a, b } Named export একসাথে Multiple export export { add, subtract };
import { a } from "..." Named import নির্দিষ্ট export নেওয়া import { useState } from "react";
import App from "..." Default import Default export নেওয়া import App from "./App.js";
import * as ns from "..." সব export এক namespace-এ Utility module import * as math from "./math.js";
import { a as b } Alias দিয়ে import Name conflict এড়ানো import { resolve as pathResolve } from "path";
Dynamic import() Runtime-এ Module লোড — Promise Code splitting, Lazy load const mod = await import("./heavy.js");
export * from "..." Re-export করা Barrel file / index.js export * from "./utils.js";

🔷 JSON — ডেটা ফরম্যাট

Method সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
JSON.stringify() Object → JSON String API request body, Storage JSON.stringify({ name: "Farid" });
JSON.stringify(val, null, 2) Formatted JSON — indented Pretty print, Debug JSON.stringify(obj, null, 2);
JSON.parse() JSON String → Object API response parse JSON.parse('{"name":"Farid"}');
JSON.parse(str, reviver) Parse করার সময় transform Date string → Date object JSON.parse(str, (k,v) => k==="date" ? new Date(v) : v);
toJSON() Stringify-এ custom output Date, BigInt serialize toJSON() { return this.id; }
JSON valid types String, Number, Boolean, null, Array, Object undefined, Function, Symbol → বাদ যায় { "key": null } ✅
Deep Clone with JSON JSON দিয়ে Deep clone — সীমিত Simple object copy JSON.parse(JSON.stringify(obj));

🔷 Iterator ও Generator — পুনরাবৃত্তি প্রোটোকল

Concept সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
Iterable Protocol Symbol.iterator method আছে এমন Object for...of-এ ব্যবহার করা যায় obj[Symbol.iterator] = function*() { yield 1; }
Iterator Protocol next() method আছে যা {value, done} দেয় Manual iteration const iter = arr[Symbol.iterator](); iter.next();
function* Generator Function — pause করা যায় Lazy sequence, Async control function* count() { yield 1; yield 2; }
yield Generator pause করে মান দেওয়া Lazy value generation yield nextValue;
yield* অন্য Iterable-এ delegate Generator compose yield* otherGenerator();
generator.next() পরবর্তী yield পর্যন্ত চালানো Step-by-step execution gen.next(); // {value: 1, done: false}
Infinite Generator শেষ না হওয়া Generator ID generator, Fibonacci function* ids() { let i=0; while(true) yield i++; }
async function* Async Generator Async stream, Paginated API async function* pages() { yield await fetchPage(1); }
for await...of Async Iterable-এ loop Stream, Async generator for await (const page of pages()) { }

🔷 Symbol — অনন্য Primitive

Concept সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
Symbol() অনন্য primitive মান তৈরি Object-এ collision-proof key const id = Symbol("id");
Symbol.for() Global registry-তে Symbol Cross-module shared Symbol Symbol.for("app.id");
Symbol.keyFor() Global Symbol-এর key বের করা Symbol lookup Symbol.keyFor(s);
Symbol.iterator Custom iteration define Iterable object তৈরি obj[Symbol.iterator] = function*() { };
Symbol.toPrimitive Type coercion customize Custom + বা comparison obj[Symbol.toPrimitive] = (hint) => { };
Symbol.toStringTag toString customize Custom type tag get [Symbol.toStringTag]() { return "MyClass"; }

🔷 Proxy ও Reflect — মেটাপ্রোগ্রামিং

Concept / Method সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
new Proxy(target, handler) Object operation intercept করা Validation, Logging, Reactive new Proxy(obj, { get(t,k) { return t[k]; } });
get trap Property read intercept Default value, Logging get(target, key) { return key in target ? target[key] : 0; }
set trap Property write intercept Validation, Reactive update set(target, key, val) { target[key] = val; return true; }
has trap in operator intercept Custom membership has(target, key) { return key in target; }
apply trap Function call intercept Function logging, Memoize apply(target, thisArg, args) { return target(...args); }
Reflect.get() Property পড়া — safe Proxy-এর ভেতরে সঠিক this Reflect.get(target, key, receiver);
Reflect.set() Property সেট করা — safe Proxy handler-এ Reflect.set(target, key, value);
Reflect.ownKeys() সব key — Symbol সহ Complete property list Reflect.ownKeys(obj);

🔷 Built-in Global Objects ও Browser API — বৈশ্বিক Object

Object / Method সংজ্ঞা ব্যবহার সংক্ষিপ্ত উদাহরণ
console.log / warn / error / table Console-এ output Debugging console.table(users);
console.time() / timeEnd() Code execution সময় মাপা Performance profiling console.time("x"); ... console.timeEnd("x");
window Browser Global Object Global scope, Browser API window.innerWidth;
globalThis Platform-নির্বিশেষে Global Object Browser + Node.js উভয়ে globalThis.fetch;
navigator Browser ও Device তথ্য Online status, User agent navigator.onLine;
navigator.geolocation Device-এর অবস্থান Map, Delivery app navigator.geolocation.getCurrentPosition(cb);
location বর্তমান URL তথ্য ও navigate Redirect, URL parse location.href = "/dashboard";
history Browser History navigate SPA routing history.pushState({}, "", "/about");
Intl.NumberFormat Locale অনুযায়ী Number format Currency, Percentage new Intl.NumberFormat("bn-BD", { style:"currency", currency:"BDT" }).format(1000);
Intl.Collator Locale-aware String sort Bengali / multilingual sort new Intl.Collator("bn").compare("আ","ক");
crypto.randomUUID() UUID তৈরি করা Unique ID generation crypto.randomUUID();
performance.now() High-resolution timestamp Precise time measurement const t = performance.now();
requestAnimationFrame() পরবর্তী repaint-এ callback Smooth animation requestAnimationFrame(draw);
Blob Binary Large Object তৈরি File download, File API new Blob([data], { type: "text/plain" });
FileReader File পড়া ও process করা File upload preview new FileReader().readAsDataURL(file);
Worker Background Thread-এ কোড চালানো CPU-heavy task UI block ছাড়া new Worker("worker.js");
structuredClone() Deep clone — built-in Object deep copy structuredClone(complexObj);
encodeURIComponent() URL-safe encoding Query param encode encodeURIComponent("হ্যালো");
decodeURIComponent() URL encoding decode URL param decode decodeURIComponent("%E0%A6%B9");
btoa() / atob() Base64 encode / decode Image data, Token btoa("hello"); // "aGVsbG8="
queueMicrotask() Microtask queue-এ task যোগ After current task, before next macrotask queueMicrotask(() => update());

🧠 নিজেকে যাচাই করো

1. Array destructuring?

2. Spread operator কী করে?

3. Optional chaining (?.) কী?

✏️ Task — এখন তুমি করো

Destructuring, spread, optional chaining — তিনটা ব্যবহার করো portfolio code-এ।

ধাপ 21🏗️ Real Project — Interactive Portfolio

🎉 JavaScript শেখা সম্পূর্ণ! Interactive Portfolio সম্পূর্ণ হলো!

🌐 HTML
🎨 CSS
⚡ JS
👁️ Browser Preview

📋 Assignment

🎉 Interactive Portfolio সম্পূর্ণ! HTML ✅ CSS ✅ JavaScript ✅ তিনটি Real Project শেষ! 💪

মাশাআল্লাহ! 🎉 এই section শেষ করেছেন — অসাধারণ! প্রজেক্টের কোডগুলো দেখে দেখে VS Code-এ নিজে টাইপ করুন — copy-paste করবেন না। কারণ হাতে টাইপ করলেই স্মৃতিতে গেঁথে যায়, মাথায় থাকে, বাস্তব অভিজ্ঞতা হয়, সাহস বাড়ে। শুধু পড়ে বা দেখে কেউ কখনো developer হয়নি। চলুন পড়ি! হাতে কলমে শিখি!