آموزش Hoisting در جاوا اسکریپت به زبان ساده
مفهوم Hoisting در جاوا اسکریپت به معنای بالا بردن است. بردن متغیرها و توابع به جایگاهی بالاتر از محل تعریف آنها. به بیان دیگر استفاده از متغیر یا تابع خاصی خارج از محدودهای که اجرای خط به خط امکان اجرای را میدهد. یعنی استفاده از یک متغیر یا تابع قبل از تعریف آن. Hoisting در جاوا اسکریپت از مفاهیمی است که در نگاه اول مخاطب را سردرگم میکند. اما اگر کمی با آن کار کنید و در مورد آن تحقیق کنید متوجه میشوید که این قابلیت قدرت عجیبی به توسعه دهنده میدهد.
در این مقاله قصد داریم این رویکرد برنامهنویسی جاوا اسکریپت را به زبانی ساده و کاربردی آموزش دهیم. پس از مطالعه این نوشته کار کردن با متغیرها در جاوا اسکریپت را به شکل فوقالعاده حرفهای و متفاوت از دیگران یاد میگیرید. تا انتها همراه ما باشید.
Hoisting در جاوا اسکریپت چیست؟
احتمالاً اصلاحاتی مانند Hoisted را در دورههای جاوا اسکریپت شنیدهاید و با خود میگویید Hoisted چیست؟ جالب است بدانید جاوا اسکریپت مکانیزمی دارد که به شما اجازه میدهد هر متغیرها را قبل از این که تعریف کنید استفاده کنید. به نظر غیرممکن به نظر میرسد. نه؟
نکته جالبتر در مورد این قابلیت این است که حتی اگر متغیری را استفاده میکنید که تعریف نکردید هیچ مشکلی در اجرای کد نخواهید داشت. جاوا اسکریپت به صورت خودکار اعلام آن را در زمان کامپایل انجام میدهد. جذابتر شد. اما داستان چیست؟
کامپایلر جاوا اسکریپت هنگام اجرای کد ابتدا تمام متغیرها را به ابتدای کد شما میآورد. قرار نیست ساختار کدی که نوشتید تغییر کند. فقط هنگام کامپایل این اتفاق میافتد. این قابلیت تضمین میکند که صرف نظر از جایی که متغیرها و توابع در چه مرحلهای از یک محدوده اعلام شدهاند، در سراسر آن محدوده قابل دسترسی هستند. ویژگیهای Hoisting در جاوا اسکریپت عبارتاند از:
- فقط اعلامها بالا میروند. مقداردهی اولیه در محل تعریف در کد معتبر است.
- امکان فراخوانی توابع قبل از اعلام آنها را فراهم میکند.
- همه متغیرها و توابع قبل از اجرای بقیه کدها پردازش میشوند.
- متغیرهای تعریف نشدهای که مورد استفاده قرار گرفتند به صورت خودکار به عنوان متغیر با Scope سراسری ساخته میشوند.
توجه: فراموش نکنید که در مورد جاوا اسکریپت فقط اعلامها را به بالا انتقال میدهد، نه مقداردهی اولیه. مقدار دهی اولیه دقیقاً جایی که کد را نوشتید اتفاق میافتد.
نکته: جاوا اسکریپت قبل از اجرای برنامه حافظه مورد نیاز برای متغیرها و توابع را به آنها اختصاص میدهد.
پیشنهاد مطالعه: Addeventlistener در جاوا اسکریپت؛ صفر تا صد
ترتیب و توالی تعریف متغیر در جاوا اسکریپت
برای این که مطلب را بهتر درک کنید بهتر است با چرخه حیات یک متغیر در جاوا اسکریپت آشنا شوید. مقداردهی اولیه متغیرها در جاوا اسکریپت «در پشت صحنه» به ترتیب زیر اتفاق میافتد.
به این ترتیب اگر بخواهیم چرخه حیات یک متغیر را با کد نشان دهیم برنامه زیر را خواهیم داشت.
let a; // Declaration a = 100; // Assignment console.log(a); // Usage
اما از آنجایی که جاوا اسکریپت به ما اجازه میدهد متغیرهای خود را به طور همزمان اعلام و مقداردهی اولیه کنیم، معمولاً این کار را به شکل زیر انجام میدهیم.
let a = 100;
نکته: طبق آنچه تا اینجا گفتیم همیشه به یاد داشته باشید که در پس زمینه جاوا اسکریپت ابتدا متغیر را اعلام میکند و سپس مقدار اولیه را به آن اختصاص میدهد. همچنین خوب است بدانید که خطوطی که در آنها متغیر اعلام میکنیم قبل از تمام کدهای دیگر پردازش میشوند.
نکته: متغیرهای تعریف نشده تا زمانی که مقدار دهی اولیه برای آنها انجام نشود، وجود ندارند. به همین دلیل کامپایلر آنها را به صورت سراسری تعریف میکند. پس به یاد داشته باشید که متغیرهای تعریف نشده سراسری بوده و در کل برنامه در دسترس هستند.
چند مثال ساده برای Hoisting در جاوا اسکریپت
برای درک بهتر مطلب لازم است چند مثال از عملکرد این مکانیزم ببینید. پس ادامه مطلب و کدها را به دقت دنبال کنید.
Hoisting در Global Scope
به کد زیر توجه کنید:
// Hoisting function codeHoist() { a = 10; let b = 50; } codeHoist(); console.log(a); // 10 console.log(b); // ReferenceError : b is not defined
خروجی کد:
10 ReferenceError: b is not defined
توضیح: در مثال بالا hoisting اجازه داده است تا متغیر a را قبل بدون این که تعریف شود مقداردهی کنیم. با توجه به این که متغیر a درون تابع است قاعدتاً نباید بتوانیم خارج از تابع از آن استفاده کنیم. اما a یک متغیر تعریف نشده است که مقدار دهی شده پس در Scope سراسری قرار دارد. به همین دلیل خارج از تابع در دسترس است.
متغیر b داخل تابع به صورت همزمان تعریف و مقداردهی شده است. پس یک متغیر تعریف شده محسوب میشود و تنها در محدوده خود در دسترس خواهد بود.
پیشنهاد مطالعه: Var در جاوا اسکریپت به زبان ساده
hoisting Var در جاوا اسکریپت
میدانیم که وقتی قبل از نام متغیر به واژههای let و const اشاره نمیکنیم جاوا اسکریپت آن را var در نظر میگیرد. جالب است بدانید رفتار مکانیزم hoisting با var شکلی متفاوت از برخورد آن با let و const دارد.
بیایید یک متغیر var تعریف کرده و رفتار hoisting را بررسی کنیم.
// var code (global) console.log(name); // undefined let name = 'Mukul Latiyan';
خروجی:
ReferenceError: Cannot access 'name' before initialization
توضیح: در مثال بالا متغیر تعریف شده با var هنگام کامپایل قبل از محل تعریف قابل استفاده است اما چون مقداردهی اولیه نشده نمیتوان از آن استفاده کرد. به این معنی که ترتیب استفاده و تعریف از متغیر مهم نیست. اما قبل از استفاده از آن حتماً باید مقداردهی صورت بگیرد. به همین دلیل در پیغام خطا گفته شده «قبل از مقداردهی نمیتوان به متغیر Name دسترسی داشت». حالا بیایید متغیر خود را قبل از استفاده و بدون مقداردهی اولیه با let تعریف کنیم.
// how interpreter sees the above code let name; console.log(name); // undefined name = 'Mukul Latiyan';
خروجی:
undefined
اگر از کلید واژه const هم استفاده کنیم همین نتیجه حاصل خواهد شد.
متغیر در محدوده تابع
بیایید بررسی کنیم که متغیرهای با محدوده تابع هنگام کامپایل چطور بالا میروند. به مثال زیر توجه کنید.
// Function scoped function fun() { console.log(name); let name = 'Mukul Latiyan'; } fun(); // Undefined
خروجی:
undefined
خروجی این مثال با مثال قبلی تفاوتی ندارد. چرا؟ گفتیم میتوانیم قبل از تعریف متغیر از آن استفاده کنیم. به این نکته هم اشاره شد که قبل از استفاده باید مقداردهی اولیه برای آن انجام دهیم. اما در این مثال مقداردهی اولیه هم صورت گرفته. پس چرا اخطار دریافت میکنیم؟ برای پاسخ به این سؤال به بخش بعدی توجه کنید.
Let hoisting در جاوا اسکریپت
ابتدا باید با کاربرد let در جاوا اسکریپت آشنا شویم. متغیری که با let تعریف میشود تنها در بلوک خود در دسترس است. اگر به مثال قبلی دقت کنید متغیر ما از کلید واژه let برای تعریف متغیر استفاده کردیم. اما خاصیت دیگری هم در مورد این عبارت وجود دارد. let همیشه مطمئن میشود که تعریف و مقداردهی متغیر حتماً قبل از استفاده آن صورت گرفته باشد.
//let example(global) console.log(name); let name = 'Mukul Latiyan'; // ReferenceError: name is not defined
خروجی به صورت زیر است:
ReferenceError: name is not defined
hoisting متغیر const در جاوا اسکریپت
متغیر const مقداری ثابت دارد و امکان تغییر و تخصیص مجدد مقدار را ندارد. پس تقدم و تأخر در آن معنی نخواهد داشت. مثال ساده زیر گویای نحوه عملکرد hoisting در هنگام مواجهه به مقدار ثابت است.
fun(); // Calling before declaration function fun() { // Declaring console.log("Function is hoisted"); }
خروجی:
Function is hoisted
در این مثال در واقع اعلام یا تعریف تابع بالا رفته است. در نتیجه مقدار ثابتی که درون آن داریم در دسترس بوده و چاپ میشود. جالب است بدانید استفاده از کلمه let برای تابع نیز از hoisting آن جلوگیری میکند. برای درک این موضوع مثال بعدی را در نظر بگیرید.
fun() // Calling the expression let fun = () =>{ // Declaring let name = 'Mukul Latiyan'; console.log(name); }
خروجی:
ReferenceError: Cannot access 'fun' before initialization
در مثال بعدی بررسی میکنیم که اگر تابع را با var تعریف کنیم چه اتفاقی خواهد افتاد.
Function hoisting در جاوا اسکریپت
به کد زیر دقت کنید. در این نمونه تابع با کلیدواژه let تعریف شده است.
fun() // Calling the expression var fun = () =>{ // Declaring let name = 'Mukul Latiyan'; console.log(name); }
خروجی:
TypeError: fun is not a function
همانطور که میبینید به دلیل وجود Var در ابتدای سطر مورد نظر Fun به عنوان یک متغیر شناسایی شده نه تابع.
پیشنهاد مطالعه: Const در جاوا اسکریپت: نگهبان مقادیر شما در دنیای متغیر
سخن پایانی
Hoisting یک مفهوم پرکاربرد در جاوا اسکریپت است که قدرت مانور برنامهنویس را به شدن افزایش میدهد. با این رویکرد دیگر لازم نیست برای تعریف یک متغیر یا تابع با ابتدای کد برگردیم. در نتیجه سرعت عمل بیشتر هم خواهیم داشت.
در این آموزش از مجله مکتب خونه تمام آنچه باید در مورد این موضوع میدانستید را با جزئیات کامل و به صورت جامع ارائه دادیم. برای کسب دانش بیشتر در مکتب خونه سری آموزشهای جاوا اسکریپت ما را دنبال کنید.
آموزش جاوا اسکریپت در مکتب خونه
جاوا اسکریپت یکی از زبانهای پر استفاده در توسعه وب به شمار میرود. این زبان ابتدا تنها برای توسعه فرانتاند طراحی شده بود. اما امروزه پیشرفتهایی به خود دیده که میتواند برنامهنویسی بکاند را هم پوشش دهد.
در نتیجه فرصتهای شغلی فراوانی برای دانشجویان آن وجود دارد؛ بنابراین پیشنهاد میکنیم برای یادگیری این زبان به صورت حرفهای و کاربردی سری به آکادمی مجازی مکتب خونه و دوره های آموزش جاوا اسکریپت و آموزش برنامه نویسی سر بزنید.
پیشنهاد مطالعه: GeeksforGeeks