مقدمه

تابع، به بیان ساده، یک بلاک کد با قابلیت استفاده‌ی مجدد است. وقتی بنا باشد کار مشخصی در جاهای مختلفی از برنامه انجام شود، می‌توانیم یک تابع تعریف کنیم که شامل کدهای مربوط به آن کار باشد. پس از تعریف یک تابع، می‌توانیم هرجا که بخواهیم، آن تابع را فراخوانی (call) کنیم تا اجرا شود. توابع، مهمترین مؤلفه‌ی ساختاری برنامه‌های جاوااسکریپت هستند. در اینجا یک معرفی مقدماتی از توابع ارائه می‌شود و در فصل دهم، موضوعات و مطالب پیشرفته‌تری در این باره بیان خواهد شد.

تعریف تابع

برای تعریف یک تابع در جاوااسکریپت، از کلمه کلیدی function و سینتکس زیر استفاده می‌شود.

function functionName() {
  // code of function block
}

پس، ابتدا کلمه کلیدی function و سپس، نامی که برای تابع در نظر گرفته‌ایم، آورده می‌شود. بعد از نام تابع هم یک جفت پرانتز دیده می‌شود. در سینتکس بالا، این پرانتزها خالی هستند اما بعداً خواهیم دید که یک تابع می‌تواند شامل یک یا چند پارامتر ورودی هم باشد که در این صورت، این پارامترها درون پرانتزهای تابع قرار می‌گیرند. این سینتکس تعریف تابع را function declaration می‌نامند.

Copy Icon functions.js
function sayHello() {
  console.log("Hello, world!");
}
            
sayHello();
sayHello();

در این مثال، تابعی با نام sayHello() تعریف شده که یک پیغام را در کنسول چاپ می‌کند. در ادامه، این تابع را دو بار فراخوانی کرده‌ایم و بنابراین، کد بدنه‌ی این تابع دو بار اجرا می‌شود و نتیجه‌ی زیر نمایش داده می‌شود.

Hello, world!
Hello, world!
          

همین مثال ساده یک قابلیت مهم توابع، یعنی قابلیت استفاده‌ی مجدد (reusability) را نشان می‌دهد. ما می‌توانیم کدی را که فقط یک بار نوشته‌ایم، هر چند بار که بخواهیم اجرا کنیم و اگر بعداً بخواهیم مثلاً متن پیام را عوض کنیم، کافیست فقط در یک جا این ویرایش را انجام دهیم.

متغیرهای Local و Outer

متغیری که درون بدنه‌ی یک تابع تعریف شود، یک متغیر local یا بومی برای آن تابع محسوب می‌شود. چنین متغیری در بیرون از بلاک تابع در دسترس نیست. اگر کد زیر را اجرا کنیم، با خطا مواجه خواهیم شد. چون سعی کرده‌ایم از متغیر لوکال message در بیرون از تابع استفاده کنیم.

Copy Icon functions.js
function showMessage() {
  let message = "Hello, world!";
  console.log(message);
}
            
console.log(message);

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

Copy Icon 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) {
  // code of function body
}

همانطور که می‌بینید، اگر تابع بیش از یک پارامتر داشته باشد، باید پارامترها را با کاما از هم جدا کنیم. هنگام فراخوانی یک چنین تابعی، باید مقادیری را برای پارامترهای تعریف‌شده فراهم کنیم؛ این مقادیر را آرگومان (argument) می‌نامند.

Copy Icon 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 خواهد بود.

Copy Icon functions.js
function showMessage(userName, message) {
  console.log(`${userName}: ${message}`);
}
            
showMessage("david");

نتیجه‌ی اجرای این کد، به صورت زیر خواهد بود.

david: undefined

اما در صورت تمایل، می‌توانیم هنگام تعریف تابع، یک مقدار پیش‌فرض دلخواه برای پارامتر تعیین کنیم تا اگر در فراخوانی تابع، مقداری به این پارامتر داده نشود (یا مقدار undefined داده شود)، مقدار پیش‌فرض مورد نظر به پارامتر اختصاص یابد. مثال زیر را ببینید.

Copy Icon 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 مقداری را به عنوان خروجی یا مقدار بازگشتی خود تعیین کند. تابع زیر، دو پارامتر خود را در هم ضرب می‌کند و حاصل را به عنوان خروجی برمی‌گرداند.

Copy Icon 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 را برمی‌گردانند. کد زیر این موضوع را نشان می‌دهد.

Copy Icon functions.js
function showMessage() {
  console.log("Hello");
}
            
let result = showMessage();
console.log(showMessage() === undefined); // true

پس، توابع جاوااسکریپت یا با استفاده از return expression; مقداری را برمی‌گردانند یا با استفاه از return; یا بدون استفاده از return مقدار undefined را برمی‌گردانند.