«تابع» بلوکی از کد سازمانیافته و قابلاستفادهی مجدد است که برای انجام کاری به کار میرود. راههای متعددی برای تعریف توابع در JavaScript وجود دارد. در اینجا به «اعلانهای تابع» و «عبارتهای تابع» میپردازیم. احتمالات دیگر مانند توابع پیکانی در مفاهیم دیگر پوشش داده میشوند.
روش استاندارد تعریف تابع در JavaScript، «اعلان تابع» است که به آن «تعریف تابع» یا «دستور تابع» هم میگویند.
این اعلان از کلیدواژهی function، اسم تابع و فهرستی از پارامترها تشکیل میشود که با کاما از هم جدا شدهاند و در پرانتز قرار میگیرند.
پس از آن بدنهی تابع (مجموعهای از دستورها که مشخص میکند تابع چه کاری انجام میدهد) میآید که داخل آکولاد قرار میگیرد.
function someName(param1, param2, param3) {
// ...
}
در JavaScript، تابع با نوشتن اسم تابع و سپس پرانتزهایی که آرگومانها را در خود دارند، فراخوانی (یا صدا زده) میشود.
someName(arg1, arg2, arg3);
در JavaScript، صرف نوشتن اسم تابع، تابع را فراخوانی نمیکند.
function sayHello() {
console.log('Hello, World!');
}
sayHello;
// => [Function: sayHello]
// The text representations varies between environments.
sayHello();
// => 'Hello, World!'
هنگام کار با پارامترها در بدنهی تابع، مراقب عوارض جانبی احتمالی روی مقدار اصلیای باشید که به تابع پاس داده شده است. در JavaScript، آرگومان کپیای از ارجاع به مقدار اصلی است. اینکه این موضوع در عمل چه معنایی دارد، به نوع دادهی آرگومان بستگی دارد.
مقادیر انواع دادههای اولیه تغییرناپذیر هستند. همهی «اصلاحات» همیشه یک مقدار اولیهی جدید میسازند. به همین دلیل، مقدار اصلی هرگز تحت تأثیر آنچه در بدنهی تابع بر سر آرگومان میآید، قرار نمیگیرد.
const num = 0;
function increase(number) {
number = number + 1;
}
increase(num);
num;
// => 0
برای مقادیری مانند شیءها، آرایهها و توابع متفاوت است. از آنجا که ارجاع کپی میشود، انتساب مجدد بر مقدار اصلی اثری نمیگذارد. اما چون با یک کپی سطحی سر و کار دارید، تغییر آرگومان در بدنهی تابع، مقدار اصلیای را هم که پاس داده شده بود تغییر میدهد.
const nums = [0, 1, 2, 3, 4];
function pushFive(arr) {
arr.push(5);
}
pushFive(nums);
nums;
// => [0, 1, 2, 3, 4, 5]
بهطور پیشفرض، همهی پارامترهایی که در اعلان تابع تعریف میشوند در JavaScript اختیاریاند.
اگر آرگومانهای کمتری از تعداد پارامترها به تابع داده شود، آرگومانهای غایب در بدنهی تابع undefined خواهند بود؛ به Null و Undefined نگاه کنید.
در بسیاری از موارد، اگر هیچ مقداری یا ویژگی undefined پاس داده نشود، منطقیتر است که پارامتر را با یک مقدار پیشفرض مقداردهی اولیه کنیم.
این کار را میتوان با تعیین پارامترهای پیشفرض مستقیماً در تعریف تابع انجام داد.
function someName(param1 = defaultValue1, param2 = defaultValue2) {
// ...
}
میتوان تابعی را با آرگومانهای بیشتر از تعداد پارامترهای تعریف تابع فراخوانی کرد.
همهی آرگومانها، از جمله آن آرگومانهای اضافی، در «آرایهی» arguments یافت میشوند.
همچنین میتوان توابعی تعریف کرد که هر تعداد دلخواهی از آرگومانها را بپذیرند (توابع variadic)؛ برای جزئیات بیشتر، پارامترهای rest را در عملگرهای Rest و Spread ببینید.
return
دستور return اجرای تابع را پایان میدهد و مقداری را مشخص میکند که باید به فراخوان تابع بازگردانده شود. یک تابع میتواند چندین دستور return داشته باشد.
function checkNumber(num) {
if (num === 0) {
return 'You passed 0, please provide another number.';
}
return 'Thanks for passing such a nice number.';
}
نتیجهی تابعی که مقداری را return نمیکند یا دستور return ندارد، undefined است.
در JavaScript هیچ return ضمنیای وجود ندارد.
function nakedReturn(a) {
a * 2;
return;
}
nakedReturn(1);
// => undefined
function noReturn(a) {
a * 2;
}
noReturn(1);
// => undefined
در JavaScript فقط میتوانید دقیقاً یک مقدار را بازگردانید. اگر میخواهید اطلاعات بیشتری را منتقل کنید، ابتدا باید آنها را در یک موجودیت واحد ترکیب کنید، معمولاً در یک شیء یا یک آرایه.
function divide(a, b) {
return {
quotient: Math.floor(a / b),
remainder: a % b,
};
}
اعلان تابع یک دستور مستقل است. اما گاهی مفید است که تابع را بهعنوان بخشی از یک عبارت دیگر تعریف کنید، مثلاً در یک انتساب، بهعنوان پارامتر تابع (کالبک) یا بهعنوان مقدار در یک شیء. این کار با عبارت تابع انجام میشود. نحوهی نگارش آن مانند اعلان تابع است، با این تفاوت که میتوان اسم تابع را حذف کرد تا یک تابع بینام ساخت.
const someFunction = function (param) {
// ...
};
someOtherFunction(function (param) {
// ...
});
const obj = {
someFunction: function (param) {
// ...
},
};
تابع در JavaScript یک زمینهی اجرای جدید معرفی میکند. متغیرهایی که داخل یک تابع تعریف میشوند، از بیرون آن تابع قابل دسترسی نیستند. اما متغیرهایی که در محدودهی والد (همان محدودهای که خود تابع در آن تعریف شده است) تعریف میشوند، داخل تابع قابل دسترسیاند. مستندات MDN دربارهی محدوده نمونههایی از این رفتار را نشان میدهد.
برای آشنایی بیشتر با محدودهی متغیرها در JavaScript، نگاهی به کلوژرها بیندازید.