تابع چیست؟
یک تابع برنامهی کوچکی است که دارای یک نام است و برای یک هدف خاص طراحی شده است. معمولاً یک برنامهی کامل جاوا اسکریپت شامل تعداد زیادی تابع است. که با قرار گرفتن این توابع کوچک در کنار هم و همکاری آنها، یک برنامهی بزرگ و کامل تشکیل میشود. در این فصل قصد داریم با توابع در جاوا اسکریپت آشنا شویم که یکی از مهمترین مباحث در جاوا اسکریپت و به طور کلی در برنامهنویسی هستند. این اهمیت به قدری زیاد است که امروزه یکی از شاخههای برنامهنویسی را با نام برنامهنویسی تابعی یا Functional Programming میشناسیم. در این نوع برنامهنویسی تمام کارها به واسطهی توابع انجام میشود. البته بحث در رابطه با برنامهنویسی تابعی خارج از حوزهی این کتاب است و علاقهمندان میتوانند جهت کسب اطلاعات بیشتر در رابطه با این مبحث به منابع مربوطه مراجعه فرمایند.
آنچه در این فصل میآموزید :- آشنایی با ماهیت توابع و روشهای تعریف آنها
- فراخوانی توابع
- مقادیر بازگشتی از توابع
- پارامترها و آرگومانها (Parameters and Arguments)
- حوزهی شناسهها (Identifiers Scope)
- بالا کشیدن متغیرها و توابع (Hoisting)
- آشنایی با توابع Callback و کاربرد آنها
تعریف یک تابع
در جاوا اسکریپت چندین روش برای تعریف یک تابع وجود دارد. در این بخش به بررسی دو مورد از این روشها که کاربرد بیشتری دارند میپردازیم. روش اول که سادهترین و مرسومترین روش است و با عنوان Function Declaration شناخته میشود به شکل زیر است.
function name(){
// کدهای اجرایی تابع
}
همانطور که مشاهده میکنید در این روش، تعریف یک تابع با کلمهی کلیدی function شروع شده و پس از آن نام تابع قرار میگیرد. نام تابع کاملاً اختیاری است. اما باید یک شناسهی معتبر باشد. همچنین بعد از نام تابع باید یک جفت پرانتز باز و بسته قرار دهیم و پس از آن یک بلاک کد ایجاد کنیم.
داخل بلاک کد مربوط به یک تابع میتوان هر نوع کدی را به کار برد. تمام دستوراتی که در این بخش قرار میگیرند، در زمان اجرای تابع (فراخوانی تابع)، اجرا خواهند شد. بنابراین اولین مزیت استفاده از توابع در برنامهنویسی، جلوگیری از تکرار کدها است. یعنی میتوان دستوراتی که در بخشهای مختلف یک برنامه به صورت یکسان و با ترتیب مشخص اجرا میشوند را داخل یک تابع قرار داد. سپس در هر نقطهی دلخواه از برنامه، تابع مذکور را فراخوانی کرد. به عنوان مثال دستورات زیر را در نظر بگیرید که مشخصات فردی یک کاربر را چاپ میکنند.
console.log("First name = Abbas");
console.log("Last name = Moqaddam");
console.log("Age = 33");
فرض کنید که در یک برنامهی خاص، در چندین نقطه از برنامه باید همین دستورات را اجرا کنیم تا خروجی متناسب با آن در کنسول نمایش داده شود. روشی که در ابتدا به ذهن یک برنامهنویس کم تجربه میرسد احتمالاً کپی کردن این ۳ دستور و قرار دادن آنها در نقاط مورد نظر از برنامه است. اما یک برنامهنویس با تجربه هیچگاه کدها را کپی نمیکند. در واقع این یکی از اصول برنامهنویسی حرفهای است. روش صحیح در این مسئله ایجاد یک تابع و قرار دادن دستورات فوق در آن است. پس از ایجاد چنین تابعی، در هر نقطهای از برنامه میتوان با فراخوانی آن تابع، دستورات داخل تابع را در همان نقطه اجرا کرد. تابع مورد نظر ما به صورت زیر خواهد بود.
function showBio(){
console.log("First name = Abbas");
console.log("Last name = Moqaddam");
console.log("Age = 33");
}
حال در هر نقطهای از برنامه میتوان با فراخوانی تابع showBio، خروجی مورد نظر را در کنسول نمایش داد.
فراخوانی توابع
جهت فراخوانی (یا اجرا کردن) یک تابع، کافی است نام آن تابع را به همراه یک جفت پرانتز باز و بسته به کار ببرید. مثلاً در قطعه کد زیر تابع showBio فراخوانی (یا اجرا) شده است.
showBio();
← First name = Abbas
← Last name = Moqaddam
← Age = 33
همانطور که مشاهده میکنید، تنها با اجرای یک دستور، تمام دستورات داخل تابع showBio اجرا میشوند. بنابراین پس از تعریف یک تابع، در هر نقطهای از برنامه میتوان آن تابع را فراخوانی و تمام دستورات داخل آن را اجرا کرد. در برخی موارد ممکن است یک تابع صدها بار در یک برنامه مورد استفاده قرار گیرد. در این صورت با استفاده از توابع میتوان هزاران خط از حجم برنامه را کم کرده و خوانایی برنامه را نیز بالا برد. برنامه فوق را میتوانید اینجا در CodePen اجرا کنید.
Function Expressions
روش دوم تعریف توابع، استفاده از Function Expressions است. در این روش یک تابع را به صورت بینام (Anonymous) تعریف کرده و اشارهگری به آن تابع را در یک متغیر ذخیره میکنیم. روش انجام این کار در قطعه کد زیر نشان داده شده است.
const showBio = function(){
console.log("First name = Abbas");
console.log("Last name = Moqaddam");
console.log("Age = 33");
}
در مثال فوق نیز یک تابع با همان رفتار و کارایی مثال قبلی ایجاد شده است. و برای فراخوانی این تابع نیز میتوان از نام متغیری که برای ذخیرهسازی اشارهگر تابع به کار رفته است استفاده کرد. توجه کنید که در مثال فوق از یک ثابت به جای متغیر استفاده شده است. میتوانستیم از متغیرها و کلمهی کلیدی let هم استفاده کنیم. اما برای توابع معمولاً از ثابتها استفاده میشود. حال برای فراخوانی تابع فوق دقیقاً مانند مثال قبلی میتوان دستور زیر را به کار برد.
showBio();
همچنین توجه کنید که میتوان اشارهگر یک تابع را در چندین متغیر مختلف ذخیره کرد. در نتیجه میتوان با چندین نام مختلف یک تابع خاص را فراخوانی کرد. به قطعه کد زیر توجه کنید.
let func1 = showBio; // or const func1 = showBio
func1();
← First name = Abbas
← Last name = Moqaddam
← Age = 33
مثال فوق را میتوانید اینجا اجرا کنید. در این مثال با توجه به این که هر دو متغیر showBio و func1 به یک تابع اشاره میکنند. برای اجرای تابع مذکور میتوان از هر یک از این دو نام استفاده کرد.
در جاوا اسکریپت روشهای دیگری نیز برای تعریف توابع وجود دارد که در ادامهی همین فصل با یک روش دیگر نیز آشنا خواهید شد. اما دو روش فوق، پر کاربردترین روشهای مورد استفاده در جاوا اسکریپت هستند. معمولاً برنامهنویسان مبتدی روش اول را ترجیح میدهند. اما به مرور به مواردی برخورد خواهیم کرد که استفاده از روش دوم در آنها مفیدتر خواهد بود. در این کتاب در ابتدا بیشتر از روش اول استفاده خواهیم کرد. اما به مرور روش دوم را در موارد متعددی به کار خواهیم برد.
هرچند در دو مثال فوق هیچ تفاوتی بین عملکرد دو تابع وجود ندارد. اما تفاوتهای ظریفی بین این دو روش وجود دارد که در ادامهی همین فصل به این تفاوتها نیز خواهیم پرداخت. اما فعلاً میتوانید هر دو روش را یکسان در نظر بگیرید.