تعریف انواع تابع در جاوا اسکریپت

29 اسفند 1397
Advanced-Javascript-functions

با سلام و عرض ادب خدمت همراهان گرامی روکسو، در این جلسه می خواهیم در رابطه با انواع توابع (توابع خودخوان، declare شده، expression function، arrow function و ...) و نحوه ی تعریف آن ها صحبت کنیم و همچنین نکاتی را در مورد این توابع بیان خواهیم کرد.

توابع جاوا اسکریپت

توابع در جاوا اسکریپت با کلیدواژه ی function تعریف می شوند و دو نوع اصلی دارند:

  • Function Declaration (به معنی اعلام تابع)
  • Function Expression (به معنی بیان تابع)

بنابراین بیایید در مورد آن ها صحبت کنیم!

Function Declaration

در دوره ی قبلی که به صورت خلاصه در مورد توابع جاوا اسکریپتی صحبت کردیم و توضیح دادیم که توابع با ساختار زیر اعلام می شوند:

function functionName(parameters) {
  // کد های مورد نظر شما برای اجرا در تابع
}

این دسته از توابع به صورت خودکار اجرا نمی شوند بلکه باید آن ها را فراخوانی کنیم یا به قول خودمانی تر «صدا بزنیم» (به انگلیسی می گوییم invoke کردن). ماهیت آن ها این طور است که برای استفاده در آینده ذخیره می شوند. مثال:

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Functions</h2>

<p dir='rtl'>این مثال شامل یک دستور است که تابعی را فراخوانی می کند و سپس تابع محاسباتی را انجام داده و مقداری را بر می گرداند. این تابع از نوع اول (اعلام شونده) است:</p>

<p id="demo"></p>

<script>
var x = myFunction(4, 3);
document.getElementById("demo").innerHTML = x;

function myFunction(a, b) {
  return a * b;
}
</script>

</body>
</html>

مشاهده ی خروجی در JSBin

نکته: از نقطه ویرگول ها برای جداسازی دستورات قابل اجرا در جاوا اسکریپت استفاده می شود و از آنجا که declare کردن یک تابع اجرایی نیست (گفتیم که این نوع توابع در همان لحظه اجرا نمی شوند تا زمانی که فراخوانی شوند)، دیگر نیازی به گذاشتن نقطه ویرگول در تعریف آن ها (پس از براکت پایانی) نیست.

Function Expression

راه دیگر تعریف کردن توابع جاوا اسکریپتی، تعریف کردنشان از طریق expression است. این نوع توابع درون یک متغیر ذخیره می شوند:

<!DOCTYPE html>
<html>
<body>

<p dir='rtl'>ذخیره کردن توابع نوع دوم درون یک متغیر:</p>
<p id="demo"></p>

<script>
var x = function (a, b) {return a * b};
document.getElementById("demo").innerHTML = x;
</script>

</body>
</html>

مشاهده ی خروجی در JSBin

پس از آنکه این نوع تابع را در متغیری تعریف نمایید، می توانید از آن متغیر به عنوان یک تابع استفاده کنید. مثال زیر به طور واضح این موضوع را نشان می دهد:

<!DOCTYPE html>
<html>
<body>

<p dir='rtl'>پس از آنکه این نوع تابع را در متغیری تعریف کنید می توانید از آن متغیر به عنوان یک تابع استفاده کنید:
</p>

<p id="demo"></p>

<script>
var x = function (a, b) {return a * b};
document.getElementById("demo").innerHTML = x(4, 3);
</script>

</body>
</html>

مشاهده ی خروجی در JSBin

به تابعی که در مثال بالا می بینید anonymous function می گویند (به معنی «تابع ناشناس») چرا که هیچ اسمی ندارد. این نوع توابع همیشه با نام متغیر مورد نظر فراخوانی می شوند.

نکته: اگر دقت کنید در تابع بالا از نقطه ویرگول استفاده کرده ایم چرا که قسمتی از یک دستور اجرایی است.

Function() Constructor

از مثال های قبل دیدید که توابع جاوا اسکریپتی با کلیدواژه ی function تعریف می شوند اما راه دیگری نیز برای تعریف توابع در جاوا اسکریپت وجود دارد. می توانیم از یک constructor استفاده کنیم: ()Function

به مثال زیر توجه کنید:

<!DOCTYPE html>
<html>
<body>

<p>JavaScript has an built-in function constructor.</p>
<p id="demo"></p>

<script>
var myFunction = new Function("a", "b", "return a * b");
document.getElementById("demo").innerHTML = myFunction(4, 3);
</script>

</body>
</html>

مشاهده ی خروجی در JSBin

سوال: آیا توابع خاصی داریم که برای تعریف کردن آن ها باید از constructor کمک بگیریم؟

پاسخ: خیر! این تنها یک روش از چندین روش تعریف توابع جاوا اسکریپتی است. مثال قبلی را می توانید به سادگی زیر بنویسید:

<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
var myFunction = function (a, b) {return a * b}
document.getElementById("demo").innerHTML = myFunction(4, 3);
</script>

</body>
</html>

Hoisting در توابع جاوا اسکریپتی

در دوره ی قبل در رابطه با مبحث hoisting صحبت کردیم (ر.ک به مقاله ی مبحث Hoisting در جاوا اسکریپت) که به طور خلاصه می گوید:

رفتار پیش فرض جاوا اسکریپت این است که declaration ها (اعلام ها) را به بالاترین قسمتِ scope فعلی ببرد.

این مبحث برای متغیرها و توابع صادق است و به همین دلیل می توانیم توابع جاوا اسکریپت را قبل از آنکه تعریف کنیم، صدا بزنیم:

myFunction(5);

function myFunction(y) {
  return y * y;
}

اما اگر توابع را با expression ها تعریف کنیم دیگر hoist نمی شوند و نمی توانیم این کار را بکنیم.

توابع خودخوان (Self-Invoking)

self-invoking کردنِ توابع یعنی خودشان، خودشان را فراخوانی کنند و نیازی به صدا زده شدن و فراخوانی جداگانه نداشته باشند. شما می توانید با قرار دادن پرانتز مقابل Function expression ها، آن ها را خودخوان کنید.

نکته: function declaration قابلیت خودخوان شدن را ندارند.

به مثال زیر توجه کنید:

<!DOCTYPE html>
<html>
<body>

<p>Functions can be invoked automatically without being called:</p>

<p id="demo"></p>

<script>
(function () {
  document.getElementById("demo").innerHTML = "Hello! I called myself";
})();
</script>

</body>
</html>

مشاهده ی خروجی در JSBin

همانطور که می بینید برای خودخوان کردن توابع باید ابتدا کل تابع را درون یک جفت پرانتز قرار دهید و سپس مقابل آن یک جفت پرانتز دیگر قرار دهید!

جالب است بدانید به تابع مثال بالا anonymous self-invoking function (به معنی «تابع خودخوان ناشناس») می گویند.

نکته: شما می توانید از توابع به صورت یک مقدار جداگانه استفاده کنید:

<!DOCTYPE html>
<html>
<body>

<p id="demo"></p>

<script>
function myFunction(a, b) {
  return a * b;
}
var x = myFunction(4, 3) * 2;
document.getElementById("demo").innerHTML = x;
</script>

</body>
</html>

مشاهده ی خروجی در JSBin

همانطور که مشاهده می شود، ما توانستیم از یک تابع به عنوان یک مقدار عادی استفاده کرده و آن را وارد محاسبات خودمان کنیم (در مثال بالا، حاصل تابع را در 2 ضرب کردیم).

Arrow Function

این دسته از توابع که جدیدا به جاوا اسکریپت اضافه شده اند به شما اجازه می دهند توابع را به صورت خلاصه تری تعریف کنید:

// مثال در ES5
var x = function(x, y) {
  return x * y;
}

// مثال در ES6
const x = (x, y) => x * y;

از آن جا که این توابع به در ES6 معرفی شده اند و به دلیل مسائل دیگر (نداشتن کلیدواژه ی this، پشتیبانی نشدن در IE11 و نسخه های قبل تر و ...) پیشنهاد می کنیم از این روش استفاده نکنید. مخصوصا از آن جهت که این روش هیچ مزیتی نسب به روش های دیگر ندارد.

امیدوارم این قسمت مورد پسند شما واقع شده باشد.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری جاوا اسکریپت پیشرفته توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما (1 دیدگاه)

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

soroush
16 اردیبهشت 1400
از این نوع فانکشن هم می توان استفاده کرد {}<=()

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.