اینجا یک متن ساده، روان و کاملاً فنی برای تو آماده کردم که میتوانی در مصاحبه دقیقاً به همین زبان بیان کنی. سعی کردم خیلی شماتیک و قابلدرک باشد:
"هویستیگ (Hoisting) در جاوااسکریپت یعنی مراحل کامپایل شدن کد قبل از اجرا. در این مرحله، موتور جاوااسکریپت تمام تعاریف (Declarations) را به بالای محدوده (Scope) خودش منتقل میکند. اما نکته مهم اینجاست که همه نوع هویستیگ با هم یکسان نیستند و تفاوت آنها در مقداردهی اولیه و
TDZاست.
۱. Function Declarations (تعریف توابع با
function):
اینها کاملترین نوع هویستیگ را دارند. یعنی هم اسم تابع و هم بدنهٔ آن به بالا میرود. به همین دلیل میتوانیم قبل از تعریف تابع، آن را صدا بزنیم و خطایی نمیخورد.
۲. متغیرهای
var:
اینها هویستیگ میشوند، اما فقط اسم آنها به بالا میرود و مقداردهیاش در همان جای خودش میماند. به همین دلیل اگر قبل از مقداردهی به آن دسترسی داشته باشیم، مقدارundefinedرا دریافت میکنیم و خطا نمیدهد.
۳. متغیرهای
letوconst:
اینجا بحث اصلیTDZیا Temporal Dead Zone پیش میآید. این متغیرها هم هویستیگ میشوند، اما موتور جاوااسکریپت آنها را در یک ناحیهٔ مردهٔ زمانی قرار میدهد. یعنی از شروع محدوده (Scope) تا خطی که متغیر تعریف شده، دسترسی به آن ممنوع است. اگر قبل از خط تعریف، بخواهیم بهletیاconstدسترسی پیدا کنیم، برنامه با خطایReferenceErrorمتوقف میشود، چون در TDZ گیر کردهایم."
میتوانی این را هم اضافه کنی:
"هر دو در TDZ قرار دارند، اما تفاوت در مقداردهی اولیه است. متغیر
letرا میتوانیم بدون مقدار اولیه تعریف کنیم (مقدارشundefinedمیشود)، اماconstحتماً در همان خط تعریف، باید مقداری داشته باشد، وگرنه خطای Syntax میدهد."
اگر خواستی خیلی حرفهای به نظر برسی، این جمله را آخرش بگو:
"پس درک این موضوع به ما میگوید که بهترین کار این است که همیشه متغیرها و توابع را در بالای محدوده خود تعریف کنیم تا از سردرگمی و خطاهای TDZ جلوگیری کنیم."
"اگر اجازه بدید، با چند مثال ساده نشون میدم که توی عملیات چطوریه:"
function (هویستیگ کامل):javascript
sayHello(); // خروجی: "Hello World!" function sayHello() { console.log("Hello World!"); }
"اینجا خطا نمیدهیم، چون کل تابع به بالا رفته."
var (هویستیگ اسم، مقدار undefined):javascript
console.log(name); // خروجی: undefined var name = "Ali"; console.log(name); // خروجی: "Ali"
"موتور جاوااسکریپت این کد رو اینطوری میبینه:"
javascript
var name; // فقط اسم بالا رفته console.log(name); // undefined name = "Ali"; console.log(name); // "Ali"
let و const (خطای TDZ):javascript
console.log(age); // ReferenceError: Cannot access 'age' before initialization let age = 30;
"با اینکه
ageهویستیگ شده، ولی تا خط سوم که مقداردهی بشه، توی منطقه ممنوعه (TDZ) قرار داره. این یعنی جاوااسکریپت بهمون میگه: 'میدونم این متغیر رو داری، ولی فعلاً اجازه دسترسی نداری!'"
let و const در مقداردهی:javascript
let firstName; // کاملاً اشکالی نداره، مقدارش undefined میشه const lastName; // SyntaxError: Missing initializer in const declaration
سوال: "آیا class در جاوااسکریپت هم هویستیگ داره؟"
پاسخ شما:
"بله، کلاسها هم هویستیگ میشن، اما درست مثلletوconstدر TDZ قرار میگیرن. یعنی اگر قبل از تعریف کلاس، نمونهسازی (new) کنیم، خطایReferenceErrorمیخوریم. این کار عمدی طراحی شده تا برنامهنویسی تمیزتری داشته باشیم."
سوال: "اگر همزمان var و function همنام داشته باشیم چی میشه؟"
پاسخ شما:
"توابع اولویت بالاتری دارن و توی هویستیگ، تابع برvarغلبه میکنه. ولی اگر بعداً تابع رو بازنویسی کنیم، مقدار جدید جایگزین میشه. این جزو نکات سختگیرانهست و دقیقاً به خاطر همین هست که استفاده ازvarدیگه توی کدهای مدرن توصیه نمیشه."
سوال: "TDZ دقیقاً از کجا شروع میشه و کجا تموم؟"
پاسخ شما:
"از ابتدای محدوده (اسکوپ) مثل بلاک{ }یا خود تابع شروع میشه و تا خطی کهletیاconstتعریف شدن ادامه داره. به محض اینکه خط تعریف رد شد، TDZ تموم میشه و متغیر قابل دسترسه."
"در کل، هاستینگ یه رفتار جالب در موتور جاوااسکریپته که میتونه مفید باشه (مثل توابع) یا باعث خطاهای عجیب بشه (مثل
var). به خاطر همین، توی تیمهای حرفهای ازletوconstاستفاده میکنیم و همیشه متغیرها رو اول اسکوپ تعریف میکنیم تا کد قابل پیشبینی و خوانا باشه. اینطوری دیگه سورپرایز TDZ رو نداریم!"
میتونی این جمله رو هم اضافه کنی:
"جالب اینجاست که توی
ES6، خودletوconstطوری طراحی شدن که برنامهنویس رو مجبور کنن کد بهتری بنویسه و از اشتباهات رایج مثل استفاده از متغیر قبل از مقداردهی جلوگیری کنن. این یعنی TDZ یه دوسته، نه یه دشمن! "