در ساده ترین تعریف ممکن، Hoisting یک رفتار پیشفرض از مفسر جاوا اسکریپت هست که متغیر ها و فانکشن ها میتونن قبل از اینکه تعریف بشن، مورد استفاده قرار بگیرن
console.log(name); var name;
خروجی کد بالا دقیقا مثل کد زیر هست: (هر دو undefined هستن)
var name; console.log(name);
خیلی از دوستان تصورشون از مفهوم Hoisting اینه که مفسر جاوا اسکریپت تعریف متغیر ها و توابع (variables and functions declaration) رو در زمان اجرای کد منتقل میکنه به بالاترین نقطه از اون Scope تا بقیه کد ها بدون گرفتن خطا بتونن از این متغیر ها و توابع استفاده کنن، ولی حقیقتش اینطور نیست، در حقیقت مفسر جاوا اسکریپت قبل از اجرای کدها، کد هارو اسکن میکنه و تعریف متغیر ها و توابع (variables and functions declaration) رو اضافه میکنه به حافظه، به همین دلیل زمان اجرا خطا نمیگیرید.
مفهوم هویستینگ فقط در تعریف متغییر ها وجود داره، به کد زیر دقت کنید:
var name; console.log(name); name = "masoudharooni"
کد بالا خروجی undefined رو نمایش میده، همونطور که گفتم هویستینگ فقط برای تعریف متغیر هستش، اگر من بعد از استفاده از یک متغیر مقداری رو به اون اختصاص (assing کنم ) بدم، اون مقدار لحاظ نمیشه، کد زیر هم دقیقا خروجی مشابه داره:
console.log(name); var name = "masoudharooni"
توی هویستینگ متغیر داخل scope ای در دسترس هست که تعریف شده، به مثال زیر دقت کنید:
function sayHello(){ b = "hello" console.log(b); var b; } sayHello(); console.log(b);
در کد بالا با صدا زدن تابع sayHello عبارت hello در خروجی چاپ میشه، ولی در خط بعد اومدیم log کردیم متغیر b رو که داخل تابع sayHello تعریف شده، اینجا ما خطای
b is not defined
رو دریافت میکنیم.
مفهوم Hosting فقط برای متغییر هایی وجود داره که با استفاده از کلیدواژه var تعریف شدن، در حقیقت اگر شما با استفاده از let یا const یک متغیر (البته که const متغییر نیست، شما از من بپذیرید ??) رو تعریف کنید دیگه لازم نیست نگران Hoisting باشید.
به مثال زیر دقت کنید:
name = "masoud" console.log(name); let name;
این تکه کد با خطا مواجه میشه:
connot access 'name' before initialization
هویستینگ در توابع
شما یک تابع رو قبل از اینکه تعریف بشه هم میتونید صدا بزنید، به مثال زیر دقت کنید:
sayHello(); function sayHello (){ conosle.log("hello!"); } # output: hello!
ولی اگر به شکل
expression اون تابع رو تعریف کنیم به این شکل نیست:
sayHello(); const sayHello = function (){ console.log("hello!"); } # output: sayHello is not defined
سعی کنید حدالامکان از Hoisting اجتناب کنید، چون خیلی از اوقات باعث به وجود اومدن یکسری مشکلات توی برنامتون میشه.