شهریار
شهریار
خواندن ۳ دقیقه·۵ سال پیش

Hoisting در جاوا اسکریپت به زبان ساده

یکی از چیزهایی که خیلی از توسعه‌ دهنده‎های جاوا اسکریپت باهاش برخورد کردند، کلمه‌ی Hoisting ـه، اونم بخاطر اینه که هربار خطای عجیب غریبی توی برنامه دیدن، تو گوگل سرچش کردند و سر از Stackoverflow در آوردند و اونجا یه بابایی داشت میگفت که این خطا بدلیله Hoisting رخ داده ?


خب واقعا Hoisting چیه؟

اگر تازه وارد دنیای جاوا اسکریپت شده باشید، احتمالا رفتار عجیبش که بعضی وقتها انگار به شکل تصادفی متغیرها رو با undefined و RefrenceError تعریف می‌کنه رو دیدید. اینجور مواقع اکثرا Hoisting رو اینجوری تعریف می‌کنند: " جاوا اسکریپت ( در زمان اجرا ) تمام متغیرها و توابع رو در بالای فایل قرار میده "؛ اما راستش.. نهه... با اینکه شاید اینطور به نظر بیاد، ولی اینجوری نیست ?

زمانی که جاوا اسکریپت فایل اسکریپت مارو دریافت می‌کنه، اولین کاری که برای ذخیره اطلاعاتی که توی کد ما هست میکنه، راه اندازی و چیدمان حافظه ـست . هیچ کدی توی این مرحله اجرا نمیشه، فقط خیلی ساده برای اجرای بهتر برنامه جاوا اسکریپت بدون در نظر گرفتن مقادیر، اعلام توابع و متغیرها رو ذخیره می‌کنه.

توی این مرحله، شکلی که اعلام توابع و متغیرها ذخیره می‌شند کمی متفاوته. توابع به شکل کامل و با آدرس‌دهی به کل تابع ذخیره می‌شند.

اما متغیرها کمی متفاوت هستند. ES6 دو تعریف جدید برای اعلام کردن متغیرها معرفی کرد: let و const. متغیرهایی که با این دو کلمه اعلام بشند به شکل uninitialized در حافظه قرار می‌گیرند. ( یجور یعنی بارگیری یا شروع نشده )

متغیرهایی که با کلمه‌ی var اعلام بشند، در حافظه به شکل undefined ذخیره‎ میشند.

زمانی که مرحله چیدمان حافظه تمام شد، برنامه می‌تونه راحت وارد مرحله اجرای کدها بشه. بیاید ببینیم که اگر قبل از اعلام توابع و متغیرها دستور console.log رو در بالای فایل اجرا کنیم چه جوابی میگیریم.

از اونجایی که توابع با آدرس‌دهی کامل به کل تابع ذخیره میشند، با فراخوانی‌شون حتی قبل از اعلام کردنشون، میتونیم به شکل کامل بهشون دسترسی داشته باشیم! ?

زمانی که قبل از اعلام یه متغیر با تعریف var بخوایم بهش رجوع کنیم، جاوا اسکریپت خیلی ساده مقداری رو که باهاش اون متغیر رو ( توی مرحله قبل ) ذخیره کرده برمیگردونه، یعنی undefiend. اگرچه شاید در بعضی اوقات، این موضوع باعث رفتارهای غیر قابل پیش‌بینی بشه؛ در بیشتر اوقات این معنی رو میده که شما بطور ناخواسته به این متغیر رجوع کردید (در هر صورت فکر نکنم بخواید که جواب متغیرتون undefiend باشه ?)

برای اینکه یوقت به شکل تصادفی undefiend رو در جواب به متغیرهای اعلام شده با var دریافت نکنید ( و این باعث گیج شدن برنامه نویس بشه )، هر زمانی که بخواید به متغیرهای let , const قبل از اعلامشون دسترسی پیدا کنید، خطای RefrenceError برگشت داده میشه. این متغیرها قبل از اینکه اعلام بشند، توی شرایطی قرار میگیرند که بهش میگند Temporal dead zone، محیط مرگ موقت؟ میتونیم بگیم برزخ طور، برای همین نمیتونید قبل از اعلام شدنشون فراخوانیشون کنید ( و انتظار مقدار صحیح داشته باشید ) و به همین علت پیغام RefrenceError براتون برگشت داده میشه.

زمانی که موتور جاوا اسکریپت ( در زمان اجرای کد ) به اعلام متغیرها میرسه، مقدار اونها رو در حافظه بازنویسی می‌کنه.

به آخرش رسیدیم! ? مروری کوتاه:

  • توابع و متغیرها قبل از اجرای کد، برای مرحله اجرا در حافظه ذخیره می‌شند که به این Hoisting میگند.
  • توابع با آدرس‌دهی کامل به کل اون تابع ذخیره میشند، ولی متغیرها متفاوتند. متغیرهای var به شکل undefiend و متغیرهای let , const به شکل uninitialized در حافظه قرار می‌گیرند.




✔️ توی کامنت‌ها نظرتون رو راجع به این مقاله بنویسید، براتون مفید بود؟ یا اگر فکر می‌کنید میشه بهتر و ساده‌تر Hoisting رو تعریف کرد حتما حتما برام بنویسید.

✔️ اگر موضوعی توی جاوا اسکریپت یا در کل دنیای برنامه نویسی تحت وب هست که دوست دارید راجع بهش مقاله‌ای تالیف/ترجمه بشه حتما برام بنویسید.

✔️ این مقاله ترجمه‌ی مقاله‌ی بسیار عالی خانم Lydia Hallie بود که ‌می‌تونید از اینجا متن اصلی رو ببینید.

✔️ مطلب قبلی من در مورد جاوا اسکریپت رو هم می‌تونید از طریق لینک زیر بخونید.

https://virgool.io/@shxhryar/javascript-runtime-environment-cad9snkl9syj



جاوا اسکریپتبرنامه نویسیjavascripthoistingاینترنت
Musician / WebHead
شاید از این پست‌ها خوشتان بیاید