Hoisting

در جاوااسکریپت، Hoisting به معنی بالا بردن (یا انتقال) تعریف متغیرها و توابع به بالای Scope خودشون قبل از اجرای کد است.
به عبارت ساده، جاوااسکریپت قبل از اجرای کد، تعاریف var و توابع را پردازش می‌کند و به بالای Scope منتقل می‌کند.

🔹 Hoisting برای توابع

توابعی که با Function Declaration تعریف می‌شوند، کامل Hoist می‌شوند و می‌توان قبل از تعریف آن‌ها فراخوانی کرد:

sayHello(); function sayHello() { console.log("Hello!"); }

📌 خروجی:

Hello!

اما توابع Function Expression با var فقط نام متغیر را Hoist می‌کنند، نه مقدار تابع را:

sayHi(); // خطا: sayHi is not a function var sayHi = function() { console.log("Hi!"); };

🔹 Hoisting برای متغیرها

1. متغیرهای var

  • نام متغیر Hoist می‌شود، اما مقداردهی نه.

  • قبل از مقداردهی، مقدار آن undefined است.

console.log(a); // undefined var a = 5; console.log(a); // 5

2. متغیرهای let و const

  • Hoist می‌شوند اما در "Temporal Dead Zone" (TDZ) قرار دارند.

  • قبل از مقداردهی، دسترسی به آن‌ها خطا ایجاد می‌کند.

console.log(b); // خطا: Cannot access 'b' before initialization let b = 10;

🔹 Temporal Dead Zone (TDZ)

  • محدوده‌ای است که متغیر با let یا const Hoist شده ولی هنوز مقداردهی نشده است.

  • هر دسترسی قبل از مقداردهی باعث خطا می‌شود.

{ console.log(x); // خطا let x = 5; }

🔹 نکات کلیدی

  1. Function Declaration → کامل Hoist می‌شود.

  2. Function Expression → فقط نام متغیر Hoist می‌شود.

  3. var → نام متغیر Hoist می‌شود، مقداردهی نه.

  4. let / const → Hoist می‌شوند ولی در TDZ هستند و قبل از مقداردهی دسترسی غیرمجاز است.

  5. Hoisting فقط تعریف‌ها را بالا می‌برد، اجرا و مقداردهی در جای خودش انجام می‌شود.

✅ خلاصه

  • Hoisting باعث می‌شود بتوانیم توابع و متغیرها را قبل از تعریف فراخوانی کنیم (با محدودیت‌ها).

  • برای کاهش خطا و کد خواناتر، بهتر است همیشه متغیرها را قبل از استفاده تعریف کنیم و از let/const به جای var استفاده کنیم.