آشنایی کامل با Hoisting در Javascript - قسمت 3 - Hoisting در ES5



visibility  
mode_comment   ۰

در جلسه قبلی توضیحات و مثالهایی رو برای hoisting قرار دادیم و شما رو تا حدی با اون آشنا کردیم. در این جلسه قصد داریم در مورد مکانیزم Hoisting در ES5 یا Ecmascript 5 توضیحاتی رو قرار بدیم.

تعریف متغیر با var

Scope یا دامنه متغیری که با استفاده از کلمه کلیدی var تعریف میشه، زمینه اجرا یا execution context فعلی هست. یعنی اگر متغیری رو با استفاده از var درون یک تابع تعریف کنیم، دامنه یا Scope اون متغیر فقط همون تابع هست و بیرون از تابع به اون متغیر دسترسی نداریم. اما اگر خارج از تابع یک متغیر رو با استفاده از var تعریف کنیم، دامنه اون متغیر سراسری یا global هست و در همه جای برنامه به اون متغیر دسترسی داریم. پس میشه گفت در ES5 دامنه تعریف متغیرها Function Scope هست، یعنی هر متغیر درون هر تابعی که تعریف بشود، فقط درون همون تابع به اون دسترسی خواهیم داشت. اگر اصلا از var استفاده نکنیم با اون متغیر مثل یک متغیر سراسری رفتار میشه و اونم بخاطر این هست که اجرا کننده بصورت ضمنی متغیر رو در دامنه یا حوزه سراسری برای ما میسازه. حالا مثالهایی رو میزنیم تا با این مفاهیم بهتر آشنا بشید.

متغیرهای سراسری یا global:

کد زیر رو در نظر بگیرید:

در ابتدا پیش خودمون فکر میکنیم، چون متغیر بعد از Console.log قرار داده و تعریف شده، پس باید در خروجی ارور ReferenceError: hoist is not defined رو مشاهده کنیم. اما چیزی که در Console چاپ میشه مقدار undefined هست! چه اتفاقی در پس زمینه افتاده است؟!

مقداری کد رو با هم بررسی میکنیم و با هم میبینیم که چه اتفاقی افتاده. همونطور که در جلسه قبل هم اشاره شد، قبل از اینکه اجرا کننده خط به خط کدها رو اجرا کنه، یک مرحله انجام میشه و همه متغیرهایی که تعریف شدن مشخص میشن و به بالای Scope انتقال داده یا Hoist میشن. پس کد بالا زمانی که اجرا کننده به اون میرسه بصورت زیر میشه:

به همین دلیل هست که میتونیم قبل از تعریف متغیرها، به اونا دسترسی داشته باشیم. اگر چه باید این رو هم در نظر داشته باشیم که ما مقدار نسبت داده شده به متغیر رو نخواهیم داشت و این مورد بخاطر این هست که متغیرهای hoist شده با مقدار اولیه undefined مقدار دهی میشن و به همین دلیل هست که ما در خروجی مقدار undefined رو میبینیم. بهترین کاری که میتونیم انجام بدیم اینه که متغیرها رو قبل از اینکه مورد استفاده قرار بدیم، هم تعریف کنیم و هم اونا رو مقدار دهی کنیم.

متغیرهای محلی یا local و function scope:

متخصص وردپرس
قالب ها و پلاگین های حرفه ای وردپرس رو خودت بنویس! بازار طراحی قالب و پلاگین نویسی وردپرس به شدت داغه و اگر بلد باشید با برنامه نویسی اختصاصی، قالب ها و پلاگین های دلخواه بنویسید تو مارکت های مطرح دنیا و یا از طریق فریلنسری می تونید به درآمد بالا برید. دوره متخصص وردپرس سون لرن رو حتما ببینید: متخصص وردپرس arrow_back

همونطور که در بالا دیدیم، متغیرهایی که در حوزه سراسری تعریف میشن، به بالای Scope انتقال داده و Hoist میشن. حالا میخوایم بررسی کنیم که متغیرهایی که در تابع تعریف میشن و function scope هستن به چه صورت hoist میشن. کد زیر رو در نظر بگیرید:

کد بالا رو بررسی کنید و پیش خودتون فکر کنید که چه مقداری در console چاپ خواهد شد. اگر حدس شما undefined هست، درست حدس زدید و اگر اشتباه کردید، نگران نباشید. در زیر این کد رو با هم بررسی میکنیم. مرحله قبل از اجرای کد انجام میشه و متغیرهای تعریف شده به بالای Scope خودشون hoist میشن. پس کد بالا بصورت زیر در میاد:

چون متغیر مورد نظر در تابع تعریف شده، scope متغیر همین تابع خواهد بود. پس این متغیر به بالای scope خودش انتقال داده و hoist میشه. پس زمانی که در خط 7 تابه hoist صدا زده میشه، مقداری که در Console نمایش داده میشه، مقدار undefined هست. بدلیل اینکه مقداردهی به متغیر message بعد از console.log صورت گرفته است. برای جلوگیری از این اشتباهات و تله ها، بهتر هست که هم تعریف و هم مقداردهی قبل از استفاده از متغیر مورد نظر باشه. کد زیر رو در نظر بگیرید:

در کد بالا چون هم تعریف و هم مقدار دهی قبل از استفاده از اون انجام شده است، مقدار مورد نظر در خروجی نمایش داده خواهد شد و دیگه با undefined روبرو نمیشیم.

حالت سخت گیر یا Strict mode:

به لطف امکانی که در ES5 به Javascript اضافه شده که همه ما اون رو به نام Strict mode میشناسیم، میتونیم در مورد تعریف متغیرهامون دقت بیشتری رو به خرج بدیم. با فعال کردن حالت strict mode ما وارد حالت متفاوت و سخت گیر تری از Javascript میشیم و در اون اجازه نداریم از متغیرهایی که قبلا تعریف نشدن، استفاده کنیم. ما میتونیم حالت strict mode رو برای کل کد و دامنه سراسری یا فقط دامنه مربوط به یک تابع، فعال کنیم. برای اینکار باید یکی از دو رشته زیر رو در ابتدای کل کد یا در ابتدای تابع مورد نظر قرار بدین:

میتونین از quote یا double quote استفاده کنید و هیچ فرقی با هم ندارند. بیاید این حالت رو با هم تست کنیم. کد زیر رو در نظر بگیرید:

اگر این کد رو در مرورگر اجرا کنیم، با خروجی زیر روبرو میشیم:

بخاطر اینکه ما قصد داریم در این حالت یک متغیر که قبلا تعریف نشده رو مقدار دهی کنیم، با یک ارور مواجه خواهیم شد. اگر قصد دارید بصورت کامل با strict mode آشنا بشید، میتونین این لینک رو مشاهده کنید.

امیدوارم از این مطلب خوشتون اومده باشه.

موفق و پیروز باشید.

یا علی

comment دیدگاه کاربران
ارسال نظرات

کاربر گرامی، امکان ارسال نظر و پشتیبانی برای دوره های مجازی فقط برای دانشجویان این دوره امکان پذیر می باشد.