تخفیف ویژه

آشنایی کامل با Hoisting در Javascript - قسمت 5 - Hoisting مربوط به توابع

دسته بندی: آموزش
زمان مطالعه: 4 دقیقه
۲۱ خرداد ۱۳۹۶

در جلسه قبل شما رو با مکانیزم Hoisting در Ecmascript 6 آشنا و نکاتی که نیاز بود رو بیان کردیم. در این جلسه مکانیزم Hoisting رو برای توابع بررسی میکنیم و حالات مختلفی که ممکن هست برای توابع به وجود بیاد رو قرار میدیم.

توابع در Javascript تقریبا در دو دسته زیر، طبقه بندی میشن:

  • Function Declaration
  • Function Expression

حالا یکی یکی موارد بالا رو با هم بررسی و مکانیزم Hoisting رو در دو نوع تابع بالا تست میکنیم.

بررسی Function Declaration:

Function Declaration بصورت زیر هست:

function hoisted() {
  console.log('This function has been hoisted.');
};

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

hoisted();

function hoisted() {
  console.log('This function has been hoisted.');
};

میبینید که تابع رو در خط 3 تعریف کردیم و در خط 1 اون رو صدا زدیم. به لطف Hoisting این عمل امکان پذیر هست و متن مورد نظر در خروجی Console نمایش داده می‌شود.

بررسی Function Expression:

این توابع بصورت زیر تعریف میشن:

var expression = function() {
  console.log('Will this work?');
};

همونطور که میبینید در این نوع توابع، یک تابع بی نام یا Anonymous رو به یک متغیر نسبت دادیم. حالا مثلا اگر بخوایم قبل از تعریف این نوع توابع، بهش دسترسی داشته باشیم، با ارور مواجه خواهیم شد. کد زیر رو ببینید:

expression();

var expression = function() {
  console.log('Will this work?');
};

در اینجا هم Hoisting صورت میگیره ولی بصورت زیر:

var expression;

expression();

expression = function() {
  console.log('Will this work?');
};

همونطور که میبینید فقط تعریف متغیر expression به بالای scope انتقال داده شد و اون قسمتی که تابع رو به متغیر نسبت دادیم، سر جای خودش باقی مانده است. حالا در خط 3 تابع expression رو صدا میزنیم. اما قبل از خط 3 تابعی برای متغیر expression نسبت داده نشده و مثل این میمونه که بخوایم undefined رو صدا بزنیم. از اونجا که undefined تابع نیست، پس با ارور زیر مواجه خواهیم شد:

اگر expression و declaration رو با هم ادغام کنیم، کدمون بصورت زیر میشه:

expression();

var expression = function hoisting() {
  console.log('Will this work?');
};

در این حالت نیز مانند حالت بالا یک ارور در Console نمایش داده میشه و بهمون میگه که expression یک تابع نیست. پس اگر بخواید به توابع از نوع expression دسترسی داشته باشید، باید حتما بعد از تعریف، اونا رو صدا بزنید.

ترتیب اولویت

زمانی که دارید متغیرها و توابع در Javascript رو مخصوصا زمانی که نام اونا با هم برابر هستند، تعریف میکنید، باید تعدادی نکته رو بخاطر بسپارید:

  1. Variable Assignment بر function declaration تقدم و برتری دارد
  2. function declaration بر variable declaration تقدم و برتری دارد

بیاید این موارد رو با هم بررسی کنیم.

مورد 1:

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

var double = 22;

function double(num) {
  return (num*2);
}

console.log(typeof double);

همونطور که میبینید در خط 1 یک متغیر double رو تعریف و Assign یا مقداردهی کردیم و در خط 3 نیز یک function declaration با نام double رو تعریف کردیم. در خط 7 میخوایم نوع double رو درون Console چاپ کنیم. بنظر شما نوع double چه خواهد بود؟ number یا function؟

در این موارد هست که باید از قواعد و استاندارد استفاده کنیم. همونطور که در نکته 1 گفته شد، variable assignment بر function declaration تقدم و اولویت داره و به همین دلیل در کد بالا، اون جایی که مقدار 22 را به متغیر double نسبت دادیم، برتری خواهد داشت و در Console عبارت number چاپ میشه.

مورد 2:

var double;

function double(num) {
  return (num*2);
}

console.log(typeof double);

تنها فرقی که کد بالا با کد قبل داره این هست که Assignment رو از خط 1 حذف کردیم و با توجه به نکته 2، function declaration بر variable declaration تقدم دارد، پس نوع double برابر با function خواهد شد. اگر در کد بالا جای  declaration‌ها را نیز تغییر بدیم، باز هم همین نتیجه به وجود میاد.

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

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

یا علی

چه امتیازی به این مقاله می دید؟
نویسنده محمد اسفندیاری
بسیار به طراحی وب علاقمندم و به سرعت در حال یادگیری تمام مباحث پیشرفته هستم و دوست دارم که به دیگران هم یاد بدهم.

نظرات کاربران

اولین دیدگاه این پست رو تو بنویس !

نیاز به لاگین

برای ارسال دیدگاه و یا پرسیدن سوال خود در این قسمت، باید در سایت لاگین شوید.