জাভাস্ক্রিপ্টের হোইস্টিং (hoisting) মূলত এক ধরনের আচরণ, যেখানে ভ্যারিয়েবল এবং ফাংশন ডিক্লেয়ারেশনগুলো তাদের সিকোয়েন্স অনুযায়ী শীর্ষে (top) নিয়ে চলে আসে, কিন্তু ভ্যালু বা অ্যাসাইনমেন্ট সেই ডিক্লেয়ারেশনের পরে ইন্টারপ্রেট করা হয়।
এখন, এটা যদি একটু সহজ ভাষায় বলি: যখন আমরা কোড লিখি, তখন ভ্যারিয়েবল বা ফাংশন ডিক্লেয়ারেশনের ঠিক আগে সেগুলো জাভাস্ক্রিপ্ট ইঞ্জিনের কাছে চলে যায়, এবং সেগুলোকে এক ধরনের “টাইমলাইনে” আগে থেকে রেজিস্টার করা হয়। তবে, অ্যাসাইনমেন্ট বা ফাংশনের বডি এর সাথে হোইস্টিং হওয়ার বিষয়টা আলাদা।
তাহলে চল, শুরু করি ভ্যারিয়েবল এবং ফাংশন হোইস্টিং এর ব্যাপারে:
১. var
এবং হোইস্টিং
var
দিয়ে যখন একটি ভ্যারিয়েবল ডিক্লেয়ার করা হয়, তখন সেটি হোইস্ট হয় কিন্তু ভ্যালু (অ্যাসাইনমেন্ট) হয় না।
console.log(a); // undefined
var a = 5;
console.log(a); // 5
এখানে, প্রথম console.log(a)
-তে undefined
দেখানো হয় কারণ var
ডিক্লেয়ারেশনটি হোইস্ট হয়ে উপরে চলে আসে, কিন্তু অ্যাসাইনমেন্টের সময় তা ঘটে না। এর মানে, a
এর ভ্যালু অ্যাসাইনমেন্টের আগে undefined
থাকবে।
var
হোইস্টিং এর আচরণ:
- ডিক্লেয়ারেশন উপরে চলে যায়।
- অ্যাসাইনমেন্ট ইন্টারপ্রেটেশনের সময় (যতটুকু কোড পড়ে, ততটুকু হয়)।
var a = 5;
console.log(a); // 5
২. let
এবং হোইস্টিং
let
এর সাথে হোইস্টিং ঘটলেও, let
কিছুটা আলাদা, কারণ এটা temporal dead zone নামে একটা সমস্যা তৈরি করে। এর মানে, আপনি let
এর ভ্যালু ব্যবহার করার চেষ্টা করলে, যতক্ষণ না আপনি সেটা ডিক্লেয়ার করেন, ততক্ষণ জাভাস্ক্রিপ্ট একটি এরর ফেলে দেয়।
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 10;
এখানে b
আগে হোইস্ট হয়, কিন্তু অ্যাসাইনমেন্টের আগে আপনি এটি ব্যবহার করতে পারবেন না।
let
হোইস্টিং এর আচরণ:
- ডিক্লেয়ারেশন উপরে চলে আসে।
- অ্যাসাইনমেন্ট পরে ঘটে।
- TDZ (Temporal Dead Zone):
let
ডিক্লেয়ার করার আগে তাকে এক্সেস করা যাবে না।
৩. const
এবং হোইস্টিং
const
এর সাথে let
এর মতোই হোইস্টিং ঘটে, তবে, এখানে একটু ভিন্ন আচরণ রয়েছে। আপনি যদি একটি const
ভ্যারিয়েবল ডিক্লেয়ার করার আগে তাকে এক্সেস করতে চান, তাও তেমনই ReferenceError
পাবেন।
console.log(c); // ReferenceError: Cannot access 'c' before initialization
const c = 20;
এখানে, const
ভ্যারিয়েবলটি let
এর মতোই TDZ এ থাকবে।
const
হোইস্টিং এর আচরণ:
- ডিক্লেয়ারেশন উপরে চলে আসে।
- অ্যাসাইনমেন্ট পরে ঘটে।
- TDZ:
const
ডিক্লেয়ার করার আগে এক্সেস করা যাবে না। - একবার
const
ডিক্লেয়ার করলে, আপনি আর তার ভ্যালু পরিবর্তন করতে পারবেন না।
৪. ফাংশন হোইস্টিং
ফাংশন ডিক্লেয়ারেশনও হোইস্টিং হয়, তবে তার আচরণ একটু আলাদা। ফাংশনের ডিক্লেয়ারেশন পুরোপুরি হোইস্ট হয়ে যায়, এবং আপনি ফাংশনকে কোডের যে কোনো জায়গায় কল করতে পারেন, যতক্ষণ না আপনি সেই ফাংশনটি ডিক্লেয়ার করেছেন।
myFunction(); // "Hello, world!"
function myFunction() {
console.log("Hello, world!");
}
এখানে, myFunction()
কল করা হয়েছে ডিফাইন করার আগেই। জাভাস্ক্রিপ্ট এখানে ফাংশনটি হোইস্ট করে নেবে এবং আপনি এটা একদম উপরের যেকোনো জায়গায় কল করতে পারবেন।
৫. ফাংশন এক্সপ্রেশন হোইস্টিং
তবে ফাংশন এক্সপ্রেশন (ফাংশন লিটারেল) আরেকটু আলাদা। যখন আপনি একটি ফাংশন এক্সপ্রেশন ব্যবহার করেন, তখন সেই ফাংশনটি হোইস্ট হয় না।
myFunction(); // TypeError: myFunction is not a function
var myFunction = function () {
console.log("Hello, world!");
};
এখানে, myFunction
প্রথমে undefined
থাকে কারণ এটা এক্সপ্রেশন হিসেবে ডিক্লেয়ার হয়েছে (এক্সেকিউশন কনটেক্সটে ফাঙ্কশন ভ্যারিয়েবল হিসেবে স্টোর করা থাকে), এবং এটি হোইস্ট হয় না।
সারাংশ:
var
: হোইস্ট হয়, তবে ভ্যালু পরে অ্যাসাইন হয় (undefined)।let
এবংconst
: হোইস্ট হয় কিন্তু TDZ এর কারণে আপনি এগুলোকে ডিক্লেয়ার করার আগে এক্সেস করতে পারবেন না।- ফাংশন ডিক্লেয়ারেশন: পুরোপুরি হোইস্ট হয়, এবং কোডের আগে থেকেই কল করা যেতে পারে।
- ফাংশন এক্সপ্রেশন: হোইস্ট হয় না, এবং আপনি ফাংশনকে কল করার আগে ডিফাইন করতে হবে।
এই আচরণগুলো যদি মাথায় রেখে কোড লেখেন, তবে জাভাস্ক্রিপ্টের হোইস্টিং নিয়ে কোনো সমস্যায় পড়বেন না।
টেম্পোরাল ডেড জোন (TDZ) জাভাস্ক্রিপ্টের একটি আকর্ষণীয় এবং গুরুত্বপূর্ণ কনসেপ্ট। এটি মূলত let
এবং const
ভ্যারিয়েবল ডিক্লেয়ারেশন নিয়ে ঘটে, এবং একটি “স্মার্ট” আচরণ তৈরি করে, যা কোডের ভুল ব্যবহার এড়াতে সাহায্য করে।
এখন, TDZ কী, এটা কেন ঘটে, এবং কীভাবে কাজ করে, সেগুলো বিস্তারিতভাবে জানাই।
টেম্পোরাল ডেড জোন (TDZ) কী?
টেম্পোরাল ডেড জোন হল একটি সময়সীমা যা let
এবং const
ভ্যারিয়েবল ডিক্লেয়ারেশন শুরুর এবং তাদের প্রথম আসল ভ্যালু অ্যাসাইনমেন্টের মধ্যে ঘটে। এই সময়ের মধ্যে যদি আপনি ওই ভ্যারিয়েবলটি অ্যাক্সেস করার চেষ্টা করেন, তাহলে ReferenceError
পাওয়া যাবে।
এটা মূলত সুরক্ষা ব্যবস্থার মতো কাজ করে, যাতে আপনি ভুলবশতঃ let
বা const
ভ্যারিয়েবলগুলি তাদের ডিক্লেয়ার করার আগেই ব্যবহার করতে না পারেন।
কেন TDZ তৈরি হয়?
let
এবং const
এর মধ্যে হোইস্টিং ঘটে, কিন্তু এগুলোর সাথে TDZ যুক্ত থাকে। var
এর ক্ষেত্রে, যে ভ্যারিয়েবলটি হোইস্ট হয়, তা undefined
থাকে, তবে let
ও const
এর ক্ষেত্রে, তাদের অ্যাক্সেস করার সময় ReferenceError
ফেলে দেয়, যদি আপনি ভ্যারিয়েবলটি ডিক্লেয়ার করার আগেই এক্সেস করতে যান।
এটা জাভাস্ক্রিপ্টের আচরণকে আরও সুরক্ষিত এবং প্রেডিক্টেবল করে তোলে, কারণ এটি ভুল কোডিং প্যাটার্ন যেমন ভুল ভ্যারিয়েবল রেফারেন্সিং এবং টাইপ এররকে আটকাতে সাহায্য করে।
TDZ এর সময়সূচী:
- হোইস্টিং:
- যখন আপনি একটি
let
বাconst
ভ্যারিয়েবল ডিক্লেয়ার করেন, তা হোইস্ট হয় কিন্তু তার ভ্যালু অ্যাসাইনমেন্ট ডিক্লেয়ারেশন লাইন এর পরে ঘটে।
- যখন আপনি একটি
- TDZ শুরু হয়:
- কোডের যে অংশে
let
বাconst
প্রথম ডিক্লেয়ার করা হচ্ছে, সেখান থেকে শুরু হয় TDZ। এই সময়ের মধ্যে ঐ ভ্যারিয়েবলটিকে অ্যাক্সেস করা যাবে না।
- কোডের যে অংশে
- TDZ শেষ হয়:
- যখন আপনি
let
বাconst
এর জন্য ভ্যালু অ্যাসাইন করবেন, তখন TDZ শেষ হয়। এর পর থেকে আপনি ভ্যারিয়েবলটিকে ব্যবহার করতে পারবেন।
- যখন আপনি
TDZ এর উদাহরণ:
উদাহরণ ১: let
এর সাথে TDZ
console.log(a); // ReferenceError: Cannot access 'a' before initialization
let a = 10;
এখানে, a
ডিক্লেয়ার করা হয়েছে let
দিয়ে, তবে তার অ্যাসাইনমেন্ট এখনও হয়নি। প্রথম console.log(a)
এর সময়, a
টেম্পোরাল ডেড জোনে থাকবে এবং আপনি যখন এটি অ্যাক্সেস করার চেষ্টা করবেন, তখন ReferenceError
হবে।
উদাহরণ ২: const
এর সাথে TDZ
console.log(b); // ReferenceError: Cannot access 'b' before initialization
const b = 20;
এখানে b
ভ্যারিয়েবলটি const
দিয়ে ডিক্লেয়ার করা হয়েছে, এবং তার অ্যাসাইনমেন্টের আগে এটি TDZ এর মধ্যে থাকবে। তাই, প্রথম console.log(b)
এ ReferenceError
হবে।
উদাহরণ ৩: TDZ এর শেষ
let c;
console.log(c); // undefined
c = 30;
console.log(c); // 30
এখানে, c
প্রথমে undefined হবে কারণ তা হোইস্ট হয় কিন্তু অ্যাসাইনমেন্টের আগে আপনি undefined পাবেন। কিন্তু, c
এর আসল ভ্যালু অ্যাসাইনমেন্টের পর আপনি একে ব্যবহার করতে পারবেন। এখানে TDZ এর কোনো রেফারেন্স এরর নেই কারণ ভ্যারিয়েবলটি অ্যাসাইন করার পরে ব্যবহার করা হচ্ছে।
TDZ এবং কোডের সুরক্ষা
TDZ let
এবং const
এর ব্যবহারকে আরও সুরক্ষিত করে তোলে, কারণ এটি ভুলভাল রেফারেন্সিং ও টাইপ-এরর থেকে প্রতিরোধ তৈরি করে। আপনি যেহেতু ভ্যারিয়েবলগুলো ডিক্লেয়ার করার আগেই ব্যবহার করতে পারবেন না, এর ফলে অপ্রত্যাশিত আচরণ থেকে আপনি বাঁচবেন।
উদাহরণস্বরূপ:
let userName = "John";
console.log(userName); // "John"
console.log(age); // ReferenceError: Cannot access 'age' before initialization
let age = 30;
এখানে age
ব্যবহার করার আগে সেটি ডিক্লেয়ার করা হয়নি, তাই আপনি ReferenceError
পাবেন।
সারাংশ:
- TDZ মূলত একটি সময় যা
let
এবংconst
ভ্যারিয়েবল ডিক্লেয়ারেশন এবং তাদের প্রথম অ্যাসাইনমেন্টের মধ্যে থাকে। - এই সময়ের মধ্যে, আপনি যদি ভ্যারিয়েবলটি অ্যাক্সেস করার চেষ্টা করেন, তবে
ReferenceError
পাবেন। var
এর ক্ষেত্রে এই সমস্যা নেই, কারণvar
এর ভ্যালু undefined থাকে, তাই তা অ্যাক্সেস করা যায়।- TDZ কোডের ভুল ব্যবহারের সম্ভাবনা কমায়, কারণ এটি আপনার ভ্যারিয়েবলগুলোকে ডিক্লেয়ার করার আগেই অ্যাক্সেস করতে দেয় না।
এইভাবে TDZ জাভাস্ক্রিপ্টে কোডের গুণমান বাড়াতে সাহায্য করে, বিশেষ করে সুনির্দিষ্ট এবং নির্ভরযোগ্য কোড লেখার ক্ষেত্রে।