احتمالا شما هم مثل من موقعی که براتون سوال شده که hoisting در جاوا اسکریپت چیه ؟
به این توضیح برخوردید :
جاوا اسکریپت در زمان اجرای برنامه ها فانکشن ها و متغیر هایی که با var تعریف شدن رو به بالای اسکوپ منتقل میکنه تا در صورتی که فانکشنی رو قبل از تعریفش صدا زده باشیم به ارور برخورد نکنیم .
خب این شاید این دیدگاه رو به ما بده که جاوا اسکریپت میاد و به صورت فیزیکی اون فانکشن بنده خدارو بلند میکنه و میذاره بالای اسکوپ و بعدش شروع میکنه میخونه کد رو ، که این خیلی درست نیست و دقیق نیست چون که جاوا اسکریپت اصلا کد مارو عوض نمیکنه و جای هیچی تغییری نمیکنه موقع اجرای برنامه .
پس تعریف بهتر چیه ؟ چطور میشه که اگه قبل از استفاده از یه فانکشن اون رو صدا بزنیم هم بازم درست عمل میکنه ؟ باید بگم که دلیلش hoisting هست :) خب ؟ حالا تعریف بهترش چیه ؟
قبلش باید این رو توضیح بدم که در جاوا اسکریپت ما چیزی به نام Execution Context داریم که یه مفهوم فرضی هست که اطلاعات اون قسمتی از کد رو که در حال اجرا شدن هست رو داخل خودش نگه میداره ...
و دارای 2 فاز هست به نام های creation phase و execution phase که در هر کدوم از این فاز ها یک سری عملیات انجام میشه که من نمیخوام خیلی وارد جزئیاتشون بشم ولی برای این که hoisting رو بتونم درست تعریف کنم باید یه تعریف مختصر از این فاز ها بدم ...
Creation phase :
توی این فاز اتفاقی که میوفته این هست که موتور جاوا اسکریپت میاد و داخل کد میگرده و هرجا که فانکشنی تعریف شده بود رو پیدا میکنه و داخل مموری ذخیره میکنه یعنی در واقع کل فانکشن با پارامتر هاش اگر چیزی داشته باشه ذخیره میشه و متغیر هایی که با کلمه var تعریف شدن هم ذخیره میکنه اما بهشون مقدار undefined رو میده حتی اگر مقدار داشته باشن .
execution phase :
توی این فاز موتور جاوا اسکریپت برمیگرده و حالا متغیر هایی که ذخیره کرده رو بهشون مقداری که براشون در نظر گرفته شده رو اختصاص میده و دیگه undefined نیستن و همچنین میاد و فانکشن هارو اگر جایی صدا زده شدن اجراشون میکنه .
خب ؟! hoisting کجاست الان ؟
همونجوری که گفتم جاوا اسکریپت توی creation phase میاد و متغیر ها و فانکشن هارو یه جورایی توی مموری ذخیره میکنه و زمانی که قراره اون هارو اجرا کنه حتی در صورتی که قبل از تعریف یک فانکشن بهش برسه چون از قبل اونو ذخیره کرده اون فانکشن رو میشناسه و اجراش میکنه و مشکلی از این بابت نداره ، در خصوص متغیر هایی که با var تعریف شدن هم اگر قبل از تعریفشون صداشون بزنیم میاد و بهمون مقدار undefined که تو مرحله ی creation phase بهشون اختصاص داده رو نمایش میده بهمون .
پس جاوا اسکریپت نمیاد فانکشن رو بگیره بیاره بذاره بالای کد و بعدش از بالا بخونش ! بلکه میاد و توی یه فاز اون هارو ذخیره میکنه و این باعث میشه حتی اگه زودتر از این که تعریفشون کرده باشیم هم صداشون بزنیم مشکلی براش پیش نیاد ، این احتمالا تعریف درست تری از hoisting هست :)
راستی ! شاید براتون سوال پیش بیاد که تکلیف متغیر هایی که با let و const تعریف کردیم چی میشه ؟
باید بگم که اگر متغیر هایی که با let و const تعریف شدن رو قبل از تعریفشون صدا بزنیم این بار جاوا اسکریپت بهمون اروری به نام ReferenceError میده و میگه که کلا اصلا همچین چیزی وجود نداره که من بخوام بهش دسترسی پیدا کنم ! ممکنه از این نتیجه بگیرین که خب پس جاوا اسکریپت let و const رو موقع creation phase جایی ذخیره نمیکنه و مقداری بهشون نمیده که نمیتونه بخونشون ، باید بگم که نه ! این کار رو میکنه و بهشون هم مقدار undefined میده اما بنا به دلایلی در دسترس نیستند که قبل از تعریفشون صداشون بزنیم .
این که اون دلایل چین و چطور اتفاق میوفته یه بحث دیگه س :) که اینجا جاش نیست ، اگه خیلی براتون سوال شده بود میتونید درباره ی Temporal dead zone تحقیق کنید .
امیدوارم براتون مفید بوده باشه ... موفق و خوشحال باشین ;)