Scope ও Hoisting
Scope কী, global/function/block scope, var/let/const scoping, hoisting, temporal dead zone — বাংলায়।
Scope হলো কোডের যে অঞ্চল থেকে একটি ভেরিয়েবল দেখা যায়। Hoisting হলো ঘোষণা উপরে টেনে আনার আচরণ। এই দুটি বুঝলে var-এর অদ্ভুত আচরণ আর const-এর error মিটে যায়।
Global scope
const globalName = "রহিম";
function show() {
console.log(globalName); // global-এ অ্যাক্সেস পায়
}
show(); // রহিমফাংশনের বাইরে (মডিউল/স্ক্রিপ্ট টপ-লেভেল) ঘোষিত ভেরিয়েবল global — সব জায়গা থেকে দেখা যায়। তবে অকারণ global-এ ছড়ানো (pollution) ঠিক নয়।
Function scope (var)
function test() {
var local = "ফাংশনের ভেতরে";
console.log(local); // ঠিক
}
test();
// console.log(local); // ReferenceError — বাইরে নয়var function-scoped — ফাংশনের ভেতরে ঘোষিত হলে পুরো ফাংশন জুড়ে চলে, কিন্তু if/loop-এর {} block-এর সাথে সীমাবদ্ধ না।
Block scope (let / const)
if (true) {
let a = 10;
const b = 20;
var c = 30; // var — block মেনে চলে না
}
console.log(c); // 30 — var বাইরে অ্যাক্সেসযোগ্য
// console.log(a); // ReferenceError
// console.log(b); // ReferenceError`let`/`const` block-scoped — { }-এর ভেতরেই সীমাবদ্ধ। var block মেনে চলে না, তাই বাইরে থেকে অ্যাক্সেস হয়। আধুনিক কোডে block scope-এর let/const-ই ব্যবহার করুন।
Scope chain
const global = "পৃথিবী";
function outer() {
const middle = "দেশ";
function inner() {
const local = "গ্রাম";
console.log(global, middle, local); // সব পায়
}
inner();
}
outer(); // পৃথিবী দেশ গ্রামভেতরের ফাংশন বাইরের scope-এর ভেরিয়েবল দেখে — scope chain। inner খুঁজে না পেলে outer-এ, তারপর global-এ যায় (লেক্সিক্যাল নেস্টিং)।
Hoisting — var ও function
console.log(a); // undefined (error নয়!)
var a = 5;
sayHi(); // অনুমোদিত — declaration hoist হয়
function sayHi() {
console.log("হাই");
}var এবং function declaration-কে JavaScript execution-এর আগে উপরে টানে (hoist)। var a-র মান undefined থেকে যায়, কিন্তু function সম্পূর্ণ লোড। তাই sayHi() আগেই ডাকা চলে।
Temporal Dead Zone (let/const)
// console.log(x); // ReferenceError — TDZ!
let x = 10;
console.log(x); // 10
// const-ও তাই
// console.log(y); // ReferenceError
const y = 20;let/const-ও hoist হয়, কিন্তু ঘোষণার আগের অঞ্চলে অ্যাক্সেস করলে ReferenceError — এই zone কে Temporal Dead Zone (TDZ) বলে। এটাই var-এর চেয়ে ভালো — অপ্রস্তুত অবস্থায় ব্যবহার ধরা পড়ে।
var-এর ট্র্যাপ
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 0);
}
// ৩ ৩ ৩ (একই i)
for (let j = 0; j < 3; j++) {
setTimeout(() => console.log(j), 0);
}
// ০ ১ ২ (প্রতিটি block-এ নিজের j)var loop-এ একটাই variable, তাই setTimeout ৩ বার শেষ value দেখায়। let প্রতিটি iteration-এ নতুন করে বাঁধা — এই subtlety-ই var-কে এড়ানোর কারণ।
| বিষয় | var | let | const |
|---|---|---|---|
| scope | function | block | block |
| hoist | হয় (undefined) | হয় (TDZ) | হয় (TDZ) |
| re-assign | হ্যাঁ | হ্যাঁ | না |
| আধুনিক কোডে | এড়িয়ে চলুন | দরকারে | ডিফল্ট |
scope ও hoisting জটিলতা কমাতে var পরিহার করুন — const ডিফল্ট, বদলাতে হলে let।
কমন প্রশ্ন: "Hoisting কী?" — উত্তর: ঘোষণা উপরে টানা, var→undefined, function→সম্পূর্ণ লোড, let/const→TDZ চালু, চেষ্টায় ReferenceError।