جاوا اسکریپت به زبان ساده - جلسه یازدهم - فانکشن‌‌ (پیشرفته)

ساخت وبلاگ

مباحث از جمله پاس دادن متغیر به فانکشن ها و نوشتن callback در هر فانکشن از جمله مواردی هستند که در این جلسه به آن ها خواهیم پرداخت. فرض کنید هر روز قرار است یک کار تکراری انجام دهید. مثلا هر روز صبح زود، چای، قهوه یا شیر میل کنید. اگر خوردن صبحانه یک فانکشن (یک عمل تکراری) باشد، آن وقت نوع نوشیدنی که صبح زود میل می کنید (مثل شیر، چایی و قهوه ) متغیر این فانکشن تکراری و روزانه است؛ متغیری که ممکن است هر روز بسته به نیازتان یکی را انتخاب کنید و به نتیجه ی متناسب با انتخاب متغیرتان برسید.

بعد از این مقدمه کوتاه، به سراغ یک فانکشن واقعی در جاوا اسکریپت خواهیم رفت. فرض کنید یک فانکشن نیاز دارید که اسم و فامیلی فرد را بگیرد و آن ها را به هم بچسباند. برای اینکه با یک بار نوشتن کد بتوانیم به چنین قابلیتی دست پیدا کنیم، چه باید کرد؟ باید نام و نام خانوادگی را به عنوان متغیرهای فانکشن در نظر بگیریم ! مثال های زیر را ببینید تا درک بهتری از این موضوع کسب کنید.

مثال اول:یک سری اسم شامل محمد، علی و محسن داریم. در طرف دیگر یک سری فامیلی دلخواه مثل فراهانی، صدیقی و پورقاسمی داریم. حالا یک فانکشن نیاز داریم که کارش وصل کردن اسم هر فرد به یک فامیلی باشد. برای اینکه تنها با یک بار نوشتن یک فانکشن بتوانید این کار را انجام دهید:

۱) ابتدا یک فانکشن با نام دلخواه تعریف می کنیم:

functionshowMyName() {

}

۲) تا به این جلسه ما در کنار نام فانکشن (در اینجاshowMyName) یک پرانتز خالی قرار می دادیم! این بار قرار است این پرانتزها با متغیرهای فانکشن پر شوند. در این فانکشن، ما درون پرانتز فانکشن سه متغیر با نام های name وfamily نوشته ایم. به (متغیرها) که در داخل پرانتز فانکشن نوشته می شوند، متغیرهای فانکشن یاآرگیومنت های فانکشنگفته می شود.

functionshowMyName(name,family) {

}

۳) حالا در داخل بلاک فانکشن (در واقع از باز تا بسته شدن آکولاد، بلاک و منطق اصلی فانکشن است) کار اصلی فانکشن را می نویسیم. کار اصلی فانکشن ما این است که متغیر نام و فامیلی را بگیرد و به هم بچسباند و نتیجه را به ما برگرداند. پس این وظیفه اصلی را در بلاک فانکشن تعریف می کنیم:

functionshowMyName(name,family) {

returnname+family

}

نکته: اگر جلسه پیش را به خاطر داشته باشید، درون هر فانکشن به دستوری دسترسی داریم که return نام دارد! دستورreturn در واقع کارش ارائه ی خروجی مطلوب از فانکشن است. در اینجا هم بعد از جمع کردن نام و نام خانوادگی با کمک دستورreturn، آن را به سمت کاربر باز می گردانیم!

۴) حالا نوبت به استفاده از این فانکشن است! تا به اینجای کار با نحوه نوشتن یک فانکشن دارای متغیر آشنا شده ایم! ولی چگونه باید از آن استفاده کنیم! این مرحله نحوه استفاده از یک فانکشن دارای متغیر است. به دقت به مثال زیر نگاه کنید:

varmyName = showMyName('mohammad Hossein','malek')

alert(myName)

همانطور که در این مثال دیدید، ما ابتدا نام فانکشن را نوشته ایم. همانطور که در جلسه پیش گفته شد، نوشتن نام فانکشن به همراه یک پرانتز باز و بسته، به معنای اجرای فانکشن است. سپس متغیرهای اسم و فامیل را به صورت استرینگ به فانکشن پاس داده ایم! اگر به تعریف فانکشن نگاه کنید، این فانکشن دو متغیر پاس داده شده را می گیرد و با یکدیگر جمع و نتیجه را Return می کند! پس متغیرmyName در این مثال در نهایت حاوی مقدار خروجی return شده از سوی فانکشن خواهد بود.

اگر هنوز در درک ماهیت فانکشن ها و نحوه تعریف متغیر برای آن ها مشکل دارید نگران نباشید! می خواهیم این موضوع را از جنبه ای ساده تر نگاه کنیم. برای ساده تر شدن مبحث بیایید یک مثال عینی روزمره بزنیم. یک دستگاه آبمیوه گیری را در نظر بگیرید. همانطور که این دستگاه از بخش های مختلفی تشکیل شده است که هر کدام یک کار انجام می دهد و بخش های مختلف آن با هم در ارتباط هستند، یک پروژه جاوا اسکریپت نیز از یک سری فانکشن تشکیل شده است. این فانکشن ها گاهی به هم مرتبط می شوند و گاهی ارتباطی با هم ندارند؛ ولی به طور کلی هر کدام بخشی از کار برنامه را بر عهده می گیرد و وظیفه ای که برای تعریف شده است، انجام می دهد.

شما می توانید هر نوع میوه ای را به عنوان ورودی در یک دستگاه آبمیوه گیری بیندازید و در نهایت یک مایع به عنوان نوشیدنی نهایی تحویل بگیرید. درست است که هر بار نوع ماده ورودی عوض می شود؛ ولی عملکرد و کاری که روی ماده انجام می شود همیشه یکی است. در واقع فانکشن ها هم همین قدر سر راست هستند!

وقتی ما یک فانکشن می نویسیم، در واقع یک عملکرد یا کاری را که قرار است بارها و بارها تکرار شود، در قالب یک کد مشخص تعریف می کنیم. سپس هر زمان که نیاز داشتیم این کد را مجددا استفاده می کنیم. برای اینکه بتوانیم هر بار که قصد استفاده از این تکه کد داریم، محتوای جدیدی بدان وارد کنیم و خروجی درست بگیریم، باید متغیرهایی برای آن تعریف کنیم. با نوشتن نام های دلخواه در حین ساخت یک فانکشن، این متغیرها ایجاد می شود و فانکشن شما به یک سری متغیر جدید به عنوان پارامتر دسترسی پیدا می کند.

حالا شما این قابلیت را دارید که هر بار می خواهید این فانکشن را استفاده کنید، اطلاعات دلخواهتان را به عنوان ورودی به این فانکشن پاس بدهید تا فانکشن شما متغیرهای پاس داده شده را به عنوان ورودی در محاسباتش استفاده کند. برای درک بهتر گفته های بالا، مثال دیگری می زنیم.

فرض کنید می خواهیم یک ماشین حساب ساده بنویسیم! برای آنکه هر بار دو عدد را با هم جمع کنیم چه راه حلی پیشنهاد می کنید؟ حتما می گویید یک فانکشن می نویسیم که متغیر اول و دوم را به عنوان پارامترهای فانکشن دریافت کند و حاصل نهایی را نمایش دهد! درست است. این مثال به شیوه زیر نوشته می شود:

functioncalculator(num1,num2){

returnnum1 + 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 در واقع یک فانکشن است که بعد از اتمام یک فانکشن بلافاصله اجرا می شود. هر فانکشن می تواند دارای یک یا چند 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

منوی غذاها

  • پیتزا پپرونی
  • onclick="addToBasket('add',5000)">اضافه به سبد
    onclick="addToBasket('remove',5000)">حذف از سبد
  • پیتزا مخصوص
  • onclick="addToBasket('add',4000)">اضافه به سبد
    onclick="addToBasket('remove',4000)">حذف از سبد
  • پیتزا ویژه سرآشپز
  • onclick="addToBasket('add',6000)">اضافه به سبد
    onclick="addToBasket('remove',6000)">حذف از سبد
    onclick="showFinalPrice()">نمایش قیمت کل

    فایل جاوا اسکریپت

    vartotalPrice=0;
    varfinalPrice=0; //بعد از محاسبه تخفیف - درصورت دریافت تخفیف
    varaddToBasket=function(addOrRemove,price) {
    if(addOrRemove=='add') {
    totalPrice+=price;
    alert("تومان به سبد خرید شما اضافه شد "+price)
    }
    else if(addOrRemove=='remove'){
    totalPrice-=price;
    alert("از سبد خرید شما حذف شد"+price)
    }
    }
    varsecialOffer=function() {
    offerPercentage=totalPrice* (10/100);
    finalPrice=totalPrice-offerPercentage;
    alert(finalPrice)
    }
    varshowFinalPrice=function() {
    if(totalPrice>10000) {
    secialOffer()
    }
    else{
    alert(totalPrice)
    }
    }
    اگر یکبار این کد را خودتان مطالعه کرده اید، می خواهیم یک توضیح کوتاه در مورد آن بدهیم. اول از همه از markUp اچ تی ام ال شروع می کنیم. در اینجا لیست غذاها را گذاشته ایم و در جلوی هر کدام از آن ها یک دکمه <<اضافه>> و یک دکمه <<حذف>> قرار دارد. اکشن جاوا اسکریپتی که روی دکمه ها گذاشته ایم یک فانکشن به نام addToBasket است که تنها پارامترهای آن هر بار تغییر می کند! اینجا کاربرد استفاده از متغیر در فانکشن ها مشخص می شود. به جای نوشتن ۱۰ باره یک فانکشن، سبد خرید را یک بار نوشته و متغیرهای مختلف را در آن استفاده کرده ایم.
    در فایل جاوا اسکریپت یک سری فانکشن و متغیر داریم. متغیرهای ما همان هایی هستند که در حین کد قصد تغییر و استفاده مجدد از آن ها را داریم. برای همین یک بار آن ها را به عنوان متغیرهای گلوبال یا عمومی در بالای کد تعریف کرده ایم تا هر وقت خواستیم به آن ها دسترسی داشته باشیم.
    کلیت منطق برنامه اینگونه است که با هر بار کلیک روی دکمه حذف یا اضافه به سبد خرید، فانکشن addToBasket اجرا می شود. این فانکشن دارای دو متغیر است. متغیر اول که در فانکشن با نام addOrRemove ایجاد شده است، چک می کند که کاربر قصد اضافه کردن به سبد خریدش دارد یا حذف محصول از آن! این چک کردن نیز به سادگی انجام می شود. روی دکمه اضافه به سبد خرید استرینگ "add" را در داخل پرانتز فانکشن نوشته ایم و بدین ترتیب این استرینگ را به عنوان متغیر به فانکشن پاس داده ایم و در حالت حذف استرینگ remove را نوشته ایم.
    این فانکشن در نهایت چک می کند که پارامتری که به ما پاس داده شده است چیست. اگر پارامتر ابتدایی یا همان addOrRemove دارای مقدار add بود، می فهیم که یوزر روی دکمه اضافه به سبد خرید کلیک کرده است. پس قیمت نهایی سفارش وی را با قیمت محصول جمع می کنیم و اگر حذف بود، قیمت محصول را از سبد خرید وی کسر می کنیم.
    فانکشن بعدی ما specialOffer است! گفتیم این فانکشن قرار است در صورتی که خرید کاربر بالای ۱۰ هزارتومان بود تخفیف لازم را روی قیمت سبد خرید وی لحاظ کند! به همین خاطر در این فانکشن ما ابتدا یک متغیرofferPercentage ساخته ایم که در واقع قرار است مقدار تخفیف را به تومان برای ما محاسبه کند. (میزان تخفیف می شود قیمت کل ضرب در ۱۰ درصد)!
    در نهایت نیز قیمت نهایی را از مقدار به دست آمده ازofferPercentage کم کرده ایم تا قیمت بعد از تخفیف سبد خرید محاسبه شود!
    آخرین فانکشن ما showFinalPrice است که بعد از کلیک روی دکمه نمایش سبد خرید در انتهای اچ تی ام ال صدا زده می شود. این فانکشن ابتدا چک می کند که اگر قیمت خرید کاربر بیشتر از ۱۰ هزار تومان است برای وی تخفیف لحاظ کند و سپس قیمت نهایی را در قالب پنجره alert به ما نمایش می دهد.

    سخن پایانی:

    امیدواریم در این جلسه با مفهوم فانکشن و پاس دادن متغیر به فانکشن ها که یکی از مهم ترین نکات پایه ای در جاوا اسکریپت است آشنا شده باشید. در جلسه آینده سراغ object خواهیم رفت و موضوعات مرتبط با داده ها را عمیق تر از پیش مورد بررسی قرار خواهیم داد.
    علم وفناوری...
    ما را در سایت علم وفناوری دنبال می کنید

    برچسب : نویسنده : 9elme1404c بازدید : 191 تاريخ : پنجشنبه 12 بهمن 1396 ساعت: 21:34