مقدمه
تابع، به بیان ساده، یک بلاک کد با قابلیت استفادهی مجدد است. وقتی
بنا باشد کار مشخصی در جاهای مختلفی از برنامه انجام شود، میتوانیم
یک تابع تعریف کنیم که شامل کدهای مربوط به آن کار باشد. پس از تعریف
یک تابع، میتوانیم هرجا که بخواهیم، آن تابع را فراخوانی (call)
کنیم تا اجرا شود. توابع، مهمترین مؤلفهی ساختاری برنامههای
جاوااسکریپت هستند. در اینجا یک معرفی مقدماتی از توابع ارائه میشود
و در فصل دهم، موضوعات و مطالب پیشرفتهتری در این باره بیان خواهد
شد.
تعریف تابع
برای تعریف یک تابع در جاوااسکریپت، از کلمه کلیدی
function و سینتکس زیر استفاده میشود.
function functionName() {
}
پس، ابتدا کلمه کلیدی function و سپس، نامی که
برای تابع در نظر گرفتهایم، آورده میشود. بعد از نام تابع هم یک
جفت پرانتز دیده میشود. در سینتکس بالا، این پرانتزها خالی هستند
اما بعداً خواهیم دید که یک تابع میتواند شامل یک یا چند پارامتر
ورودی هم باشد که در این صورت، این پارامترها درون پرانتزهای تابع
قرار میگیرند. این سینتکس تعریف تابع را
function declaration مینامند.
functions.js
function sayHello() {
console.log("Hello, world!");
}
sayHello();
sayHello();
در این مثال، تابعی با نام sayHello() تعریف
شده که یک پیغام را در کنسول چاپ میکند. در ادامه، این تابع را دو
بار فراخوانی کردهایم و بنابراین، کد بدنهی این تابع دو بار اجرا
میشود و نتیجهی زیر نمایش داده میشود.
Hello, world!
Hello, world!
همین مثال ساده یک قابلیت مهم توابع، یعنی قابلیت استفادهی مجدد
(reusability) را نشان میدهد. ما میتوانیم کدی را که فقط یک بار
نوشتهایم، هر چند بار که بخواهیم اجرا کنیم و اگر بعداً بخواهیم
مثلاً متن پیام را عوض کنیم، کافیست فقط در یک جا این ویرایش را
انجام دهیم.
متغیرهای Local و Outer
متغیری که درون بدنهی یک تابع تعریف شود، یک متغیر local یا بومی
برای آن تابع محسوب میشود. چنین متغیری در بیرون از بلاک تابع در
دسترس نیست. اگر کد زیر را اجرا کنیم، با خطا مواجه خواهیم شد. چون
سعی کردهایم از متغیر لوکال message در بیرون از تابع
استفاده کنیم.
functions.js
function showMessage() {
let message = "Hello, world!";
console.log(message);
}
console.log(message);
متغیرهایی که در بیرون از بلاک یک تابع تعریف شدهاند، برای آن تابع
حکم متغیرهای outer یا بیرونی را دارند. توابع جاوااسکریپت به
متغیرهای بیرونی هم دسترسی دارند و حتی میتوانند آنها را ویرایش
کنند. مثال زیر را ببینید.
functions.js
let message = "Hello";
function changeMessage() {
message = message + ", world";
}
console.log(message);
changeMessage();
console.log(message);
قبل از اجرای تابع changeMessage()، مقدار
متغیر message برابر با Hello است اما بعد از اجرای این تابع،
مقدار متغیر message تغییر میکند. نتیجهی اجرای این کد به
صورت زیر خواهد بود.
Hello
Hello, world!
متغیرهایی مانند message در مثال بالا، که بیرون از توابع
تغریف شوند، متغیرهای Global نامیده میشوند. بهتر است تا جایی که
ممکن است از تعریف متغیرهای Global خودداری کنیم. با این وجود، گاهی
اوقات، این متغیرها برای ذخیرهی مقادیر project-level، یعنی مقادیری
که باید در دسترس کل برنامه باشند، مفید هستند.
پارامترهای تابع
همانطور که قبلاً هم گفتیم، توابع میتوانند مقادیری را به عنوان
ورودی دریافت کنند. فرم کلی تعریف تابعی که دارای پارامترهای ورودی
است، به صورت زیر است.
function functionName(parameter1, parameter2, ..., parameterN) {
}
همانطور که میبینید، اگر تابع بیش از یک پارامتر داشته باشد، باید
پارامترها را با کاما از هم جدا کنیم. هنگام فراخوانی یک چنین تابعی،
باید مقادیری را برای پارامترهای تعریفشده فراهم کنیم؛ این مقادیر
را آرگومان (argument) مینامند.
functions.js
function showMessage(userName, message) {
console.log(`${userName}: ${message}`);
}
showMessage("david", "Hello my friends!");
showMessage("john", "What's up?");
تابع showMessage() دو پارامتر دارد و در هر
فراخوانی، آرگومانهایی برای این پارامترها فراهم شده است. نتیجهی
اجرای این کد، به صورت زیر خواهد بود.
david: Hello my friends!
john: What's up?
مقادیر پیشفرض پارامترها
در جاوااسکریپت، وقتی هنگام فراخوانی یک تابع، مقداری را برای یکی از
پارامترهای تابع تعیین نکنیم، خطایی رخ نمیدهد؛ بلکه مقدار
undefined برای آن پارامتر در نظر گرفته میشود. مثلاً اگر در
کد قبلی، تابع showMessage() را فقط با یک
آرگومان فراخوانی کنیم، پارامتر دوم دارای مقدار
undefined خواهد بود.
functions.js
function showMessage(userName, message) {
console.log(`${userName}: ${message}`);
}
showMessage("david");
نتیجهی اجرای این کد، به صورت زیر خواهد بود.
david: undefined
اما در صورت تمایل، میتوانیم هنگام تعریف تابع، یک مقدار پیشفرض
دلخواه برای پارامتر تعیین کنیم تا اگر در فراخوانی تابع، مقداری به
این پارامتر داده نشود (یا مقدار undefined داده شود)، مقدار
پیشفرض مورد نظر به پارامتر اختصاص یابد. مثال زیر را ببینید.
functions.js
function showMessage(userName, message = "Hello, world!") {
console.log(`${userName}: ${message}`);
}
showMessage("david");
showMessage("john", undefined);
در این مثال، پارامتر message دارای یک مقدار پیشفرض است که
در صورتی که آرگومانی برای این پارامتر فراهم نشود یا مقدار
undefined به آن داده شود، این مقدار پیشفرض به
message اختصاص پیدا میکند. بنابراین، این کد با نتیجهی زیر
همراه خواهد بود.
david: Hello, world!
john: Hello, world!
مقدار بازگشتی توابع
توابعی که تا الان دیدیم، مقداری برنمیگردانند اما یک تابع میتواند
با استفاده از کلمه کلیدی return مقداری را به
عنوان خروجی یا مقدار بازگشتی خود تعیین کند. تابع زیر، دو پارامتر
خود را در هم ضرب میکند و حاصل را به عنوان خروجی برمیگرداند.
functions.js
function multiply(a, b) {
let c = a * b;
return c;
}
let result = multiply(5, 6);
console.log(`5 * 6 = ${result}`);
در اینجا مقدار بازگشتی یا خروجی تابع در متغیری به نام
result
ذخیره شده است.
دایرکتیو return میتواند در هر جایی از بدنهی
تابع قرار داده شود و به محض رسیدن به آن نقطه، مقدار فراهمشده برای
return برگردانده شده و تابع متوقف میشود. اگر
از return بدون هیچ مقداری یعنی به فرم
return; استفاده کنیم، تابع بدون اینکه
مقداری برگرداند، متوقف میشود.
نکتهی دیگری که باید در ارتباط با توابع جاوااسکریپت بدانید این است
که حتی توابعی که صراحتاً مقداری برنمیگردانند، یعنی شامل
return نیستند یا از آن بدون مقدار استفاده
کردهاند، عملاً مقدار undefined را برمیگردانند. کد زیر این
موضوع را نشان میدهد.
functions.js
function showMessage() {
console.log("Hello");
}
let result = showMessage();
console.log(showMessage() === undefined);
پس، توابع جاوااسکریپت یا با استفاده از
return expression; مقداری را
برمیگردانند یا با استفاه از
return; یا بدون استفاده از
return مقدار undefined را برمیگردانند.