مباحث از جمله پاس دادن متغیر به فانکشن ها و نوشتن callback در هر فانکشن از جمله مواردی هستند که در این جلسه به آن ها خواهیم پرداخت. فرض کنید هر روز قرار است یک کار تکراری انجام دهید. مثلا هر روز صبح زود، چای، قهوه یا شیر میل کنید. اگر خوردن صبحانه یک فانکشن (یک عمل تکراری) باشد، آن وقت نوع نوشیدنی که صبح زود میل می کنید (مثل شیر، چایی و قهوه ) متغیر این فانکشن تکراری و روزانه است؛ متغیری که ممکن است هر روز بسته به نیازتان یکی را انتخاب کنید و به نتیجه ی متناسب با انتخاب متغیرتان برسید.
بعد از این مقدمه کوتاه، به سراغ یک فانکشن واقعی در جاوا اسکریپت خواهیم رفت. فرض کنید یک فانکشن نیاز دارید که اسم و فامیلی فرد را بگیرد و آن ها را به هم بچسباند. برای اینکه با یک بار نوشتن کد بتوانیم به چنین قابلیتی دست پیدا کنیم، چه باید کرد؟ باید نام و نام خانوادگی را به عنوان متغیرهای فانکشن در نظر بگیریم ! مثال های زیر را ببینید تا درک بهتری از این موضوع کسب کنید.
مثال اول:یک سری اسم شامل محمد، علی و محسن داریم. در طرف دیگر یک سری فامیلی دلخواه مثل فراهانی، صدیقی و پورقاسمی داریم. حالا یک فانکشن نیاز داریم که کارش وصل کردن اسم هر فرد به یک فامیلی باشد. برای اینکه تنها با یک بار نوشتن یک فانکشن بتوانید این کار را انجام دهید:
۱) ابتدا یک فانکشن با نام دلخواه تعریف می کنیم:
functionshowMyName() {
}
۲) تا به این جلسه ما در کنار نام فانکشن (در اینجاshowMyName) یک پرانتز خالی قرار می دادیم! این بار قرار است این پرانتزها با متغیرهای فانکشن پر شوند. در این فانکشن، ما درون پرانتز فانکشن سه متغیر با نام های name وfamily نوشته ایم. به (متغیرها) که در داخل پرانتز فانکشن نوشته می شوند، متغیرهای فانکشن یاآرگیومنت های فانکشنگفته می شود.
functionshowMyName(name,family) {
}
۳) حالا در داخل بلاک فانکشن (در واقع از باز تا بسته شدن آکولاد، بلاک و منطق اصلی فانکشن است) کار اصلی فانکشن را می نویسیم. کار اصلی فانکشن ما این است که متغیر نام و فامیلی را بگیرد و به هم بچسباند و نتیجه را به ما برگرداند. پس این وظیفه اصلی را در بلاک فانکشن تعریف می کنیم:
functionshowMyName(name,family) {
retuname+family
}
نکته: اگر جلسه پیش را به خاطر داشته باشید، درون هر فانکشن به دستوری دسترسی داریم که return نام دارد! دستورreturn در واقع کارش ارائه ی خروجی مطلوب از فانکشن است. در اینجا هم بعد از جمع کردن نام و نام خانوادگی با کمک دستورreturn، آن را به سمت کاربر باز می گردانیم!
۴) حالا نوبت به استفاده از این فانکشن است! تا به اینجای کار با نحوه نوشتن یک فانکشن دارای متغیر آشنا شده ایم! ولی چگونه باید از آن استفاده کنیم! این مرحله نحوه استفاده از یک فانکشن دارای متغیر است. به دقت به مثال زیر نگاه کنید:
varmyName = showMyName('mohammad Hossein','malek')
alert(myName)
همانطور که در این مثال دیدید، ما ابتدا نام فانکشن را نوشته ایم. همانطور که در جلسه پیش گفته شد، نوشتن نام فانکشن به همراه یک پرانتز باز و بسته، به معنای اجرای فانکشن است. سپس متغیرهای اسم و فامیل را به صورت استرینگ به فانکشن پاس داده ایم! اگر به تعریف فانکشن نگاه کنید، این فانکشن دو متغیر پاس داده شده را می گیرد و با یکدیگر جمع و نتیجه را Return می کند! پس متغیرmyName در این مثال در نهایت حاوی مقدار خروجی return شده از سوی فانکشن خواهد بود.
اگر هنوز در درک ماهیت فانکشن ها و نحوه تعریف متغیر برای آن ها مشکل دارید نگران نباشید! می خواهیم این موضوع را از جنبه ای ساده تر نگاه کنیم. برای ساده تر شدن مبحث بیایید یک مثال عینی روزمره بزنیم. یک دستگاه آبمیوه گیری را در نظر بگیرید. همانطور که این دستگاه از بخش های مختلفی تشکیل شده است که هر کدام یک کار انجام می دهد و بخش های مختلف آن با هم در ارتباط هستند، یک پروژه جاوا اسکریپت نیز از یک سری فانکشن تشکیل شده است. این فانکشن ها گاهی به هم مرتبط می شوند و گاهی ارتباطی با هم ندارند؛ ولی به طور کلی هر کدام بخشی از کار برنامه را بر عهده می گیرد و وظیفه ای که برای تعریف شده است، انجام می دهد.
شما می توانید هر نوع میوه ای را به عنوان ورودی در یک دستگاه آبمیوه گیری بیندازید و در نهایت یک مایع به عنوان نوشیدنی نهایی تحویل بگیرید. درست است که هر بار نوع ماده ورودی عوض می شود؛ ولی عملکرد و کاری که روی ماده انجام می شود همیشه یکی است. در واقع فانکشن ها هم همین قدر سر راست هستند!
وقتی ما یک فانکشن می نویسیم، در واقع یک عملکرد یا کاری را که قرار است بارها و بارها تکرار شود، در قالب یک کد مشخص تعریف می کنیم. سپس هر زمان که نیاز داشتیم این کد را مجددا استفاده می کنیم. برای اینکه بتوانیم هر بار که قصد استفاده از این تکه کد داریم، محتوای جدیدی بدان وارد کنیم و خروجی درست بگیریم، باید متغیرهایی برای آن تعریف کنیم. با نوشتن نام های دلخواه در حین ساخت یک فانکشن، این متغیرها ایجاد می شود و فانکشن شما به یک سری متغیر جدید به عنوان پارامتر دسترسی پیدا می کند.
حالا شما این قابلیت را دارید که هر بار می خواهید این فانکشن را استفاده کنید، اطلاعات دلخواهتان را به عنوان ورودی به این فانکشن پاس بدهید تا فانکشن شما متغیرهای پاس داده شده را به عنوان ورودی در محاسباتش استفاده کند. برای درک بهتر گفته های بالا، مثال دیگری می زنیم.
فرض کنید می خواهیم یک ماشین حساب ساده بنویسیم! برای آنکه هر بار دو عدد را با هم جمع کنیم چه راه حلی پیشنهاد می کنید؟ حتما می گویید یک فانکشن می نویسیم که متغیر اول و دوم را به عنوان پارامترهای فانکشن دریافت کند و حاصل نهایی را نمایش دهد! درست است. این مثال به شیوه زیر نوشته می شود:
functioncalculator(num1,num2){
retunum1 + num2
}
حالا هر بار بخواهیم دو عدد را جمع کنیم، کافی است از این فانکشن استفاده کنیم و دو متغیر عددی دلخواه را بدان پاس دهیم تا حاصل جمع آن ها را به ما نمایش دهد. به طور مثال می خواهیم ۵ و ۶ را از طریق این فانکشن جمع کنیم:
varfivePlusSix = calculator(5,6)
اگر جلسه قبل را دنبال کرده باشید، می دانید که لزومی ندارد که همیشه یک متغیر به فانکشن بدهید. در واقع هنگامی که یک فانکشن را صدا می زنیم، می توانیم بدون پاس دادن متغیر و به همان ترتیب جلسه قبلی عمل می کنیم:
functionmyFunction(){
//تعریف فانکشن بدون متغیر
}
myfunction()// صدا زدن یک فانکشن بدون متغیر مانند مثال های قبلی
در این حالت فانکشن ما دارای متغیر خاصی نیست. در مثال زیرmyFunction قرار است تعدادی متغیر را با هم جمع کند و نتیجه را در قالب پنجره alert نمایش دهد:
functionmyFunction(arg1,arg2,arg3) {
//درون فانکشن ما به arg1,arg2,arg3 دسترسی داریم
alert(arg1+arg2+arg3)
}
نکته جالب اینجا است که در حین صدا کردن یک فانکشن می توانید هر نوع متغیری که دوست دارید بدان پاس دهید! یعنی وقتی داریمmyFunction را صدا می زنیم، مهم نیست به جایarg1 یک عدد گذاشته ایم یا متن! هر چه گذاشته باشیم در درون فانکشن ما عملیات تعیین شده را انجام خواهد داد. برای مثال در زیر ما سه اسم پاس داده ایم:
myFunction("ali ","sina ","mohammad")
و در مثال بعدی به جای سه اسم، سه عدد را به عنوان متغیرهای فانکشن، پاس داده ایم:
myFunction("۱ ","۲ "," ۳")
ولی همانطور که در اجرای این کد مشاهده خواهید کرد، در هر حالت و با وجود متغیرهای متفاوتی که به فانکشن پاس داده ایم، در خروجی نهایی ما تفاوتی حاصل نشد. در واقع در هر سه حالت، فانکشن myFunction متغیرهایی را که بدان پاس داده ایم، صرف نظر از نام و نوع داده از ما گرفت، درون خود با اسم های arg1,arg2,arg3 جمع کرد و خروجی آن را در قالب پنجره الرت به نمایش گذاشت.
نکته اول: هر فانکشن می تواند به صورت نامحدود متغیر جدید در خود جای دهد و سپس این متغیرها را در درون خود استفاده کند.
نکته دوم:لزومی ندارد همیشه یک استرینگ یا عدد را به عنوان متغیر به فانکشن پاس بدهیم! ما حتی می توانیم داده هایی را که از پیش در برنامه تعریف شده اند، به عنوان متغیر به فانکشن پاس بدهیم! مثال زیر را ببینید تا منظورمان از نکته را بهتر درک کنید.
فرض کنید که سه متغیر با نام های name1 و name2 و name3 داریم:
varname1,name2,name3
همینجا باید بگوییم که حین تعریف چند متغیر می توانید به جای اینکه هر بار کلمه var را بنویسید، یک بار آن را بنویسید و بین متغیرهای مختلف <<,>> بگذارید. بدین ترتیب مثل این است که سه متغیر جداگانه تعریف کرده باشید.
به هر یک از این متغیرها نام دلخواهمان را نسبت می دهیم:
name1 ="ali";
name2 ="davood"
name3 ="mahnaz"
سپس یک فانکشن تعریف می کنیم. در این فانکشن می خواهیم روی مقادیر متغیرهایی که بالاتر تعریف کرده ایم تغییر ایجاد کنیم:
functionmyFunction(params1,params2,params3){
alert(params1,params2,params3)
}
این بار به جای کلمه arg از کلمه params استفاده کردیم تا بگوییم می توانید هر نامی که دلتان می خواهد به عنوان نام متغیرهای فانکشن استفاده کنید. این موضوع اهمیتی ندارد و هر نامی قابل قبول است. بدین ترتیب همه مثال های زیر درست هستند:
functionmyFunction(one,two,three) {
}
functionMyFunction(isItOk,HelloDude,ByDude) {
}
در تمامی این حالت ها فانکشن ما خودش یک سری متغیر به نام هایی که داخل پرانتز نوشته ایم می سازد و از این به بعد هر چیزی که در حین صدا شدن فانکشن بدان پاس داده می شود با این نام ها می شناسد.
۱) در حین پاس دادن پارامترها به فانکشن ها به شماره آن ها دقت کنید. برای مثال ما در زیر فانکشنی داریم که تنها یک متغیر می پذیرد:
functionmyFunction(arg1){
alert(arg1)
}
ولی در حین صدا زدن این فانکشن دو متغیر بدان پاس می دهیم:
myFunction("number1","number2")
در این حالت تنها ما بهnumber1 که اولین متغیر است و با نام arg1درون فانکشنmyFunction شناخته می شود دسترسی داریم و نمی توانیم ازnumber2 استفاده کنیم.
۲) فرض کنید فانکشنی دارید که سه پارامتر دریافت می کند:
functionmyFunction(arg1,arg2,arg3){
alert(arg1)
alert( arg2)
alert(arg3)
}
و در حین صدا زدن:
myFunction("paraph1","paraph2")
در حین صدا زدن ما تنها دو متغیر بدان پاس داده ایم! پس تکلیف پارامتر سوم چه می شود! پارامتر سوم، درون فانکشن undefined یا تعریف نشده خواهد بود و نمی توانید از آن استفاده کنید؛ چون اصلا در حین صدا زدن فانکشن تعریف نشده است.
مهمlrm;ترین مزیت این است که می توانید با یک بار نوشتن فانکشن ، یک کار ساده را با متغیرهای جدید تکرار کنید. یعنی یک بار یک فانکشن تعریف می کنید و عملیات خود را روی داده های مختلف انجام می دهید؛ بدون آنکه نیاز باشد هر بار این فانکشن را تکرار کنید.
Callback در واقع یک فانکشن است که بعد از اتمام یک فانکشن بلافاصله اجرا می شود. هر فانکشن می تواند دارای یک یا چند CallBack باشد.کال بک یکی از قابلیت های فانکشن محسوب می شود که بعد از اجرای آن فانکشن و تمام شدن تمامی موارد آن مورد استفاده قرار می گیرد. مثلا فرض کنید می خواهید بعد از اینکه فلان اتفاق در فانکشن افتاد و تمام شد، به کاربر پیغام بدهد که کار شما با موفقیت انجام شد و پیغام الرت را به وی نمایش بدهد. نمایش پیغام آلرت، کال بک فانکشن برای فانکشن اصلی شما است که به محض تمام شدن فانکشن اصلی اجرا می شود.
نکته مهم در کال بک این است که تنها زمانی اتفاق می افتد که کار فانکشن به صورت کامل و با موفقیت به اتمام رسیده باشد.
برای تعریف کال بک آخرین گزینه آرگیومنت های شما باید فانکشن کال بک باشد. بعد از تعریف کال بک، آن را با همان اسمی که در آرگیومنت ها تعریف کردیم صدا می زنیم:
functiondoSomething(callback) {
// کارهایی که فانکشن اصلی قرار است انجام دهد
// بعد از اتمام فانکشن اصلی فانکشن کال بک صدا زده می شود
callback('stuff', 'goes', 'here');
}
برای درک بهتر مثال توضیحات زیر را ببینید:
در ابتدا ما یک فانکشن کال بک که دوست داریم بعد از فانکشن اصلی اجرا شود می نویسیم (دقت کنید فانکشن کال بک باید قبل از فانکشن اصلی نوشته شود؛ چون جاوا اسکریپت کدهای شما را از بالا به پایین می خواند و اگر در حین صدا زدن فانکشن اصلی، کال بک قبلا تعریف نشده باشد، با ارور تعریف نشده روبه رو خواهید شد).
نام فانکشن کال بک ماiAmTheCallBackFunction است. این فانکشن سه متغیر a, b, c را می گیرد و آن ها را در کنار هم و با یک فاصله (اسپیس) الرت می کند.
functioniAmTheCallBackFunction(a, b, c) {
// من کال بک فانکشن هستم
alert(a +" "+ b +" "+ c);
}
حالا ما فانکشن اصلی خود را می نویسیم. نام این فانکشن mainFunction است. این فانکشن یک آرگیومنت به نامcallback دارد که در واقع همان کال بک فانکشنی است که ما می خواهیم.
functionmainFunction(callback){
//بعد از اتمام کار فانکشن ما کال بک را صدا بزن
callback()
}
حالا در حین صدا کردن فانکشنmainFunction می توانیمiAmTheCallBackFunction را که خودش یک فانکشن است به عنوان متغیر به فانکشنmainFunction پاس دهیم. سپس آن را در فانکشن اصلی استفاده کنیم. مطابق زیر:
mainFunction(iAmTheCallBackFunction);
بدین ترتیب بعد از تمام شدن فانکشن اصلی فانکشن کال بک بلافاصله صدا خواهد شد. از کال بک در موارد بسیار زیادی استفاده می شود. در جلسات آینده زمانی که سراغ setTimeOut و setInterval برویم ماهیت اصلی استفاده از فانکشن ها را خواهید آموخت.
قبل از اتمام این جلسه، می خواهیم یک مثال ساده را به صورت یک پروژه کوچک بیان کنیم تا بهتر با مفاهیم گفته شده در مورد فانکشن ها آشنا شوید. اگر خاطرتان باشد در جسات قبلی ما یک پروژه مدیریت رستوران آنلاین را آغاز کرده بودیم. حالا می خواهیم به کمک دانش فعلی مان آن را حرفه ای تر از قبل بنویسیم.
توضیح پروژه: این پروژه قرار است به کاربر امکان بدهد تا یک سری غذا انتخاب کند و در صورتی که مشتری خرید بالاتر از ۱۰ هزار تومان داشت به وی تخفیف ۱۰ درصدی بدهد.
HTML
فایل جاوا اسکریپت
برچسب:
نویسنده: باربد میرزاپور