توابع یکی از اصلیترین ستونهای جاوااسکریپت هستند. به طور کلی به دو روش اصلی میتونی یک تابع رو توی کدت بسازی: اعلان تابع (Function Declaration) و بیان تابع (Function Expression). بیا هر دو رو عمیق یاد بگیریم.
این روش معمولی و سنتی تعریف تابع هست. برای این کار از کلمه کلیدی function استفاده میکنی و اجزای زیر رو پشت سر هم مینویسی:
اسم تابع (برای اینکه بعداً بتونی صداش بزنی).
لیست پارامترها (ورودیهای تابع که داخل پرانتز میشینند و با کاما از هم جدا میشن).
بدنه تابع (دستوراتی که داخل آکلواد { } قرار میگیرند و کارهای تابع رو مشخص میکنند).
به این مثال نگاه کن؛ یک تابع به اسم square ساختیم که یک عدد میگیره و مجذورش (مربعش) رو برمیگردونه:
function square(number) {
return number * number;
}
این تابع یک پارامتر به اسم number میگیره. دستور return هم مشخص میکنه که خروجی نهایی این تابع چه مقداری باشه (یعنی ضربِ اون عدد در خودش).
توی جاوااسکریپت، وقتی یک متغیر معمولی (مثل عدد یا متن) رو به عنوان ورودی به تابع میدی، این مقدار به صورت کپی (By Value) وارد تابع میشه. یعنی اگر داخل تابع، مقدار اون پارامتر رو کلاً عوض کنی، هیچ اتفاقی برای متغیر اصلی در خارج از تابع نمیافته.
اما داستان اشیاء (Objects) و آرایهها (Arrays) کاملاً فرق میکنه! اگر یک شیء یا یک آرایه رو به عنوان پارامتر به تابع بفرستی، جاوااسکریپت آدرس اصلی اونها (By Reference) رو به تابع میده. این یعنی اگر داخل تابع، یکی از ویژگیهای اون شیء یا آیتمهای اون آرایه رو تغییر بدی، تغییراتت بیرون از تابع هم اعمال میشن و دیتای اصلی دستخوش تغییر میشه!
بیا دو تا مثال واقعیاش رو ببینیم:
// مثال اول: تغییر ویژگیهای یک شیء داخل تابع
function myFunc(theObject) {
theObject.make = "Toyota"; // ویژگی شیء ورودی رو تغییر میدیم
}
const myCar = { make: "Honda", model: "Accord", year: 1998 };
console.log(myCar.make); // خروجی: "Honda"
myFunc(myCar); // شیء رو میفرستیم داخل تابع
console.log(myCar.make); // خروجی: "Toyota" (تغییرات بیرون از تابع هم نشست!)
// مثال دوم: تغییر آیتمهای یک آرایه داخل تابع
function myFunc(theArr) {
theArr[0] = 30; // آیتم اول آرایه رو عوض میکنیم
}
const arr = [45];
console.log(arr[0]); // خروجی: 45
myFunc(arr); // آرایه رو میفرستیم داخل تابع
console.log(arr[0]); // خروجی: 30 (آرایه اصلی بیرون از تابع هم تغییر کرد!)
نکته: توابع رو میتونی به صورت تو در تو هم بنویسی. این کار یک زنجیره از محدودهها (Scope Chain) ایجاد میکنه که در بخشهای بعدی (مبحث کلوژرها) کامل بازش میکنیم.
در این روش، به جای اینکه تابع رو به صورت یک دستور مستقل بنویسی، اون رو میسازی و داخل یک متغیر ذخیره میکنی.
توابعی که به این روش ساخته میشن میتونن ناشناس (Anonymous) باشن؛ یعنی نیازی نیست بعد از کلمه function اسمی براشون بگذاری:
// تعریف تابع مجذور به روش بیان تابع و به صورت ناشناس
const square = function (number) {
return number * number;
};
console.log(square(4)); // خروجی: 16
البته اگر دوست داشته باشی، میتونی برای این مدل هم اسم بگذاری. داشتن اسم کمک میکنه که تابع بتونه داخل خودش، خودش رو صدا بزنه (کارهای بازگشتی یا Recursive) و موقع دیباگ کردن و دیدن خطاهای مرورگر هم راحتتر پیدایش کنی:
// یک تابع بازگشتی برای محاسبه فاکتوریل با نام fac
const factorial = function fac(n) {
return n < 2 ? 1 : n * fac(n - 1);
};
console.log(factorial(3)); // خروجی: 6
بیان توابع زمانی که میخوای یک تابع رو مثل یک متغیر ساده به عنوان ورودی به یک تابع دیگه پاس بدی، فوقالعاده کاربردی هستند.
به این مثال نگاه کن؛ یک تابع دستساز به اسم map داریم که یک تابع و یک آرایه میگیره، بعد اون تابع رو روی تکتکِ اعضای آرایه اجرا میکنه:
function map(f, a) {
const result = new Array(a.length);
for (let i = 0; i < a.length; i++) {
result[i] = f(a[i]); // اجرای تابعِ ورودی روی تکتک آیتمها
}
return result;
}
const numbers = [0, 1, 2, 5, 10];
// پاس دادن یک تابع ناشناس که اعداد رو به توان ۳ میرسونه:
const cubedNumbers = map(function (x) {
return x * x * x;
}, numbers);
console.log(cubedNumbers); // خروجی: [0, 1, 8, 125, 1000]
جذابیت بیان توابع اینه که میتونی تعریف شدنشون رو مشروط کنی. مثلاً بگیم این تابع فقط زمانی ساخته بشه که مقدار متغیر ما صفر باشه:
let myFunc;
if (num === 0) {
myFunc = function (theObject) {
theObject.make = "Toyota";
};
}
سازنده تابع (Function constructor): علاوه بر این روشها، میتونی با ساختار new Function() کدهای متنی (String) رو موقع اجرای برنامه تبدیل به تابع واقعی کنی (چیزی شبیه به تابع خطرساز eval()) که البته در کدهای معمولی اصلاً توصیه نمیشه.
متد (Method) چیست؟ هر زمان که یک تابع رو به عنوان یک ویژگی (Property) داخل یک شیء (Object) تعریف کنی، به اون تابع میگیم متد. در بخشهای بعدی مفصل با متدها کار میکنیم.
این محتوا کاملا رایگان توسط تیم کدلپر ترجمه شده و در اختیار شما کاربران عزیز قرار گرفته است، هر گونه کپی برداری برای مقاصد غیر رایگان و بدون ذکر منبع، مورد پیگیری قانونی قرار میگیرد.
ترجمه شده از منبع: https://developer.mozilla.org/en-US/docs/Web/JavaScript