یکی از اولین چیز هایی که هر تازه کار جاوا اسکریپت باید کامل یادش بگیره hoisting هست! پس اگر اون رو بلد نیستید این پست رو تا آخر بخونید تا در زمان اجرای کد هاتون از اون غافلگیری های معروف جاوا اسکریپت رو تجربه نکنید !!
جاوا اسکریپت در زمان کامپایل یک ذره متفاوت از اون چیزی که به نظر میاد عمل می کنه :
در زمان کامپایل تمامی تعاریف متغیر ها و تعاریف توابع شما اصطلاحا hoisted میشن و به بالای کد کشیده میشن!
برای درک بهتر این موضوع به مثال زیر نگاه کنید:
console.log(myName); var myName = ‘vahid’;
اینجا یک متغیر به نام myName تعریف کرده ایم حالا طبق چیزی که گفتیم جاوا اسکریپت قبل از اجرای کد myName را میاره در بالاترین سطح کدمون که درواقع میشه به صورت زیر:
var myName; console.log(myName); myName = ‘vahid’;
خوب حالا فهمیدیم که چرا میتونیم یک متغیر رو قبل از تعریفش مثلا console.log بگیریم!
اما یک نکته ای باید به یاد داشته باشیم اینه که جاوا اسکریپت تنها تعریف یا declaration متغیر رو hoist میکنه و نه مقدار دهی به اون رو، پس اگر کد زیر رو اجرا کنیم مقدار undefined رو تو console میبینیم:
console.log(myName); var myName = ‘vahid’; //output -> undefined
همون طوری که می دونید اگر متغیر hoist یا lift نشده بود ما خطای Uncaught ReferenceError: myName is not defined میخوردیم و اجرای کد متوقف میشد ولی اینجا متغیر رو میشناسه ولی مقدار دهی نشده است.
خوب اگه بخواهیم جمع بندی کنیم نحوه ی کامپایل کد های جاوااسکریپت رو این طوری باید در نظر بگیریم هنگام کد زدن:
فرض می کنیم کد های جاوا اسکریپت ۲ بار خوانده می شوند، در بار اول کل کد خوانده می شود و هرچی تعریف متغیر و تابع هست رو میشناسه و به بالای کد میاره اما در بار دوم خط به خط اون ها رو اجرا میکنه(مقدار دهی هم این جا انجام میشه) و اینجوری کل فایل اجرا می شود.
اما یک مثالی ار hoist شدن توابع رو هم با هم ببینیم:
hello(); function hello(){ console.log('Hello! I Was Hoisted to top! :D'); } //output -> Hello! I Was Hoisted to top! :D
طبق روالی که با هم دیدیم اینجا اول تابع hello به بالای فایل منتقل میشه و بعد موقع اجرا در بار دوم اول تابع تعریف میشهه و هنگام صدا زدن اون دیگه مشکلی نیست!
اگر می خواهید راحت تر تو ذهنتون بمونه بار اول اجرای کد رو اینجوری در نظر بگیرید که هر چی متغیر و تابع هست تعریف میشه و دیگه درگیر اومدنشون به بالای کد نشید و فقط این رو یادتون باشه که مقدار متغیر ها بار دوم داده میشه!
اگر این نکته رو در نظر نگیرید مثل کد زیر به خطا میخورید:
hello(); var hello = function hello(){ console.log('Hello! I Was Hoisted to top! :D'); } //output -> Uncaught TypeError: hello is not a function
این تکه کد شبیه مثال قبلی بود ولی error گرفتیم!
دلیلش هم اینه که اینجا ما تابع رو assign کردیم به یک متغیر به نام hello و اون رو بالاتر صدا زدیم.
خوب الان شما میدونید جاوا اسکریپت تو بار اول متغیر hello رو تعریف میکنه ولی مقدار نمیده بهش و undefined هست پس بار دوم که میخواهد کد ها رو خط به خط اجرا کند میرسه به ;()hello و طبیعتا خطا میگیریم.
کل مفهوم hoisting همین بود ولی خیلی خیلی مهمه که وقتی کد میزنیم اون رو تو ذهنمون داشته باشیم.
شاید بعضی از دست خط های جاوا اسکریپت رو دیده باشید که تمام متغیر هاشون و هم چنین توابع رو بالای کد تعریف میکنند و بعدا اون ها رو مقدار دهی میکنند که با این کار کد خودشون رو خیلی شبیه زمان اجرای اون میکنند که خوب کار جالبی به نظر میاد و میتونه error های احتمالی رو خیلی کمتر کنه.
امیدوارم تونسته باشم مفهوم hoisting رو خوب توضیح بدم :) اگر چیزی رو از قلم انداختم لطفا تو کامنت ها بنویسید:)
اگر هم براتون مفید بود لایک یادتون نره ;)