۹۷/۳/۱، ۰۴:۴۰ صبح
در دهمین جلسه آموزش جاوا اسکریپت ، به آموزش فانکشنها میپردازیم.
فانکشنها در واقع تکهکدهایی هستند که قرار است یک یا چند عملیات کلی را روی کد ما اعمال کنند. فانکشنها مانند اکشنهایی هستند که میتوانند کار خاصی را در زمانی که ما از آنها میخواهیم تکرار کنند. برای درک بهتر عملکرد فانکشنها، بدن انسان را در نظر بگیرید. قلب وظیفه پمپاژ و خونرسانی را به تمامی اعضای دیگر بدن دارد. قلب بهعنوان یک فانکشن اصلی در بدن، یک وظیفه مشخص دارد. این فانکشن، یک ورودی دریافت میکند (خون) و این ورودی را با اعمال تغییراتی، مجددا به بدن بازمیگرداند. مثال دیگر، خودرو است. در یک خودرو، سیستم سوخترسانی یک فانکشن است. با دریافت سوخت از پمپ بنزین، آن را به دیگر اعضای ماشین که به سوخت نیاز دارند منتقل میکند.
فانکشنها به دو صورت کلی نوشته میشوند:
- فانکشنهای دارای نام
- فانکشنهای بدون نام یا anonymus
تعریف فانکشن دارای اسم:
اگر بخواهیم یک فانکشن را بهگونهای بنویسیم که هر کجای برنامه قابل صدا کردن و استفاده باشد، باید به آن اسم بدهیم. فانکشنهای دارای اسم قابل صدا زدن و اجرای مجدد در هر کجای برنامه هستند. همچنین باید بدانید کد ما بهصورت خودبهخود اجرا نمیشود و تا زمانی که این فانکشن فراخوانی نشود، اتفاقی نخواهد افتاد.
برای تعریف یک فانکشن دارای اسم از روش زیر استفاده میکنیم:
*محتوای این قسمت تنها برای اعضای انجمن قابل مشاهده می باشد. *
همانطور که میبینید این بار بعد از کلمه کلیدی function که کارش تعریف فانکشن است، یک نام نوشتهایم که در واقع نام فانکشن ما محسوب میشود و از این به بعد از طریق این نام میتوانیم این فانکشن را صدا بزنیم.
میخواهیم با زدن یک دکمه فانکشنی را که قبلا تعریف کردیم صدا بزنیم.
*محتوای این قسمت تنها برای اعضای انجمن قابل مشاهده می باشد. *
برای صدا زدن این فانکشن، کافی است نام آن را به همراه دو پرانتز در کنار آن بنویسیم.
*محتوای این قسمت تنها برای اعضای انجمن قابل مشاهده می باشد. *
برای صدا کردن فانکشن دارای نام، دقت کنید که تنها نام آن را مینویسیم و پرانتز باز و بسته را قرار میدهیم که به مرورگر بفهمانیم در حال صدا زدن فانکشن خود هستیم. در صورتی که کلمه کلیدی function را مجددا بنویسیم، انگار که در حال تعریف دوباره فانکشن هستیم نه صدا زدن آن.
روش صدا زدن فانکشن :
*محتوای این قسمت تنها برای اعضای انجمن قابل مشاهده می باشد. *
روش دیگری نیز برای تعریف یک فانکشن دارای نام هست و آن ذخیره فانکشن در داخل یک متغیر است. روش صدا زدن چنین فانکشنی هیچ تفاوتی با حالت بالا ندارد.
برای این کار ابتدا یک متغیر تعریف میکنیم و فانکشن خود را بهعنوان مقدار آن مینویسیم.
مثال:
*محتوای این قسمت تنها برای اعضای انجمن قابل مشاهده می باشد. *
حالا اگر بخواهیم این فانکشن را صدا بزنیم باز هم مینویسیم:
*محتوای این قسمت تنها برای اعضای انجمن قابل مشاهده می باشد. *
همانند روالی که در جلسات گذشته داشتیم، این جلسه نیز کمی تمرین انجام میدهیم تا اطلاعاتمان کاملتر شود! فانکشن جزو موارد کلیدی جاوا اسکریپت است و به همین خاطر تمرینهای جذابتری در این جلسه منتظر شما است! آماده یادگیری موارد تازه باشید!
تمرین اول:
یک دکمه بنویسید که با کلیک روی آن تاریخ روز را نمایش دهد.
حل تمرین اول:
یکی از اتریبیوتهایی که در واقع پل رابطی بین تگهای HTML و جاوا اسکریپت محسوب میشود، اتریبیوت onclick است! این اتریبیوت بهصورت مستقیم میتواند یک فانشکن یا کد جاوا اسکریپت را اجرا کند. یعنی شما میتوانید تمام دستورات جاوا اسکریپتی خود را در درون تگ اچتیامال و بهعنوان مقدار onclick بنویسید یا کمی هوشمندانهتر برخورد کنید و یک فانکشن مشخص برای کلیک هر تگ اچتیامال تعریف کنید! ما در این مثال روش اول و دوم را بررسی میکنیم:
روش اول: نوشتن همه کدها در داخل تگ اچتیامال
*محتوای این قسمت تنها برای اعضای انجمن قابل مشاهده می باشد. *
در همین جا که در حال نوشتن یک استرینگ در داخل یک اتریبیوت هستیم یک نکته کوچک جالب وجود دارد! وقتی میخواهیم به یک اتریبیوت اچتیامال مقدار بدهیم بعد از مساوی و نام اتریبیوت، علامت سینگل کوتیشن ' ' یا دابل کوتیشن " " قرار میدهیم. مثلا اتریبیوت کلاسهای سیاساس به این صورت نوشته میشود:
*محتوای این قسمت تنها برای اعضای انجمن قابل مشاهده می باشد. *
اتریبیوت آن کلیک نیز همین گونه دارای سینگل یا دابل کوتیشن است. ولی ما از قبل میدانیم که در جاوا اسکریپت، استرینگها نیز باید در بین سینگل یا دابل کوتیشن قرار بگیرند! پس باید حواسمان باشد هر جا که قرار است دو بار از کوتیشن استفاده شود، باید ترکیبی از سینگل و دابل کوتیشن را استفاده کنیم! برای همین مثال اتریبیوتهای اچتیامال، میتوانیم مقدار اتریبیوت را که بعد از مساوی آن قرار میگیرد، با سینگل کوتیشن بنویسیم و کدهای جاوا اسکریپت خود را در داخل دابل کوتیشن بنویسیم! بدین صورت مرورگر میفهمد که کدام یک نشانگر باز و بسته شدن استرینگ و کدام یک مربوط به اتریبیوت اچتیامال است.
البته این موضوع در محیطهای توسعه یا IDE-ها (مثل visual Studio) بهصورت کامل توسط قابلیت هایلایت مشخص است و میتوانید بروز خطا در کدهایتان را کاملا متوجه شوید!
به ادامه تمرین باز میگردیم. میخواستیم بعد از کلیک روی دکمه، تاریخ نمایش داده شود. برای این کار یک فانکشن مینویسیم. بدین ترتیب هر زمان بخواهیم میتوانیم با یک بار نوشتن کد نمایش تاریخ آن را نمایش دهیم. یعنی برای مثال میتوانیم به هر نوع تگ دیگری هم یک اتریبیوت onclick اضافه کنیم و این فانکشن را بهعنوان مقدار پاس دهیم تا همین کار را برایمان انجام دهد.
فایل HTML
*محتوای این قسمت تنها برای اعضای انجمن قابل مشاهده می باشد. *
حالا وارد فایل جاوا اسکریپت میشویم و یک فانکشن با همین نام که در اتریبیوت اچتیامال گفتهایم تعریف میکنیم:
ابتدای صفحه یک متغیر عمومی برای ذخیره تاریخ تعریف میکنیم؛ متغیری که با هر بار صدا کردن فانکشن مقدار آن با تاریخ روز عوض و برابر میشود.
سپس یک فانکشن برای دریافت زمان روز تعریف میکنیم. داخل این فانکشن ما از یک فانکشن پیشفرض قرار دادهشده در جاوا اسکریپت به اسم Date() استفاده میکنیم. این فانکشن هر جا که صدا زده شود، تاریخ دقیق را بهصورت روز و حتی ثانیه به ما میدهد. روال استاندارد استفاده از تابع تاریخ اینگونه است که ابتدا آن را در یک متغیر بریزیم و قبل از صدا زدن فانکشن از کلمه کلیدی new استفاده کنیم تا یک آبجکت جدید از تابع تاریخ برای ما ساخته شود. میدانیم که کمی مبحث پیچیده و گنگ به نظر میرسد؛ ولی چندان خود را درگیر نامها نکنید! همه این موضوعات در آینده بررسی خواهد شد! فعلا فقط بدانید که گرفتن تابع تاریخ بهصورت زیر خواهد بود.
*محتوای این قسمت تنها برای اعضای انجمن قابل مشاهده می باشد. *
اگر حالا کد خود را اجرا کنید، خواهید دید که با کلیک روی دکمه «امروز چندم است»، تگ اچتیامال با آیدی showTime تغییر پیدا میکند و تاریخ روز را نمایش میدهد! به همین سادگی!
document.getElementById چیست و چه کار میکند؟
در این جلسه یک توضیح مختصر میدهیم؛ ولی توضیح تکمیلی را به جلسه مخصوص انتخاب تگهای اچتیام ال در جاوا اسکریپت موکول میکنیم.
اینطور فرض کنید که همیشه باید یک پل رابط بین اچتیامال و جاوا اسکریپت وجود داشته باشد که به کمک آن بتوانیم محتوای اچتیامال صفحه را تغییر بدهیم. این پل رابط را یک آبجکت به نام document در نظر بگیرید! در واقع فرض کنید یک درخت (ظرف، جعبه یا هر چیز دیگری) بزرگ به نام document داریم که تمامی تگهای اچتیامال و محتویات صفحه را در بر میگیرد. هر یک از تگهای اچتیامال شاخههای این درخت هستند!
برای گرفتن یک شاخه از این درخت باید به نحوی آن را انتخاب کنیم. برای انتخاب چند راه پیشرو داریم. انتخاب توسط آیدی المان یکی از راهها است و برای این کار از دستوراتی مثل getElementById استفاده میکنیم. این دستور دنبال یک المان اچتیامال با id که به آن میدهیم میگردد و آن را برای تغییر توسط جاوا اسکریپت آماده میکند. بعد از انتخاب المان اچتیامال میتوانیم هر گونه تغییری که خواستیم روی آن اعمال کنیم. مثلا میتوانیم محتوای اچتیامال آن را با کمک دستور innerHTML تغییر بدهیم. در اینجا ما هم چنین کاری را انجام دادهایم.
return در فانکشن
اگر خاطرتان باشد، در همین ابتدای آموزش گفتیم که فانکشنها یک ورودی بهعنوان متغیر دریافت میکنند و سپس فعل و انفعالاتی روی این ورودی صورت میگیرد و نتیجه در قالب خروجی به ما داده خواهد شد.
برای دریافت خروجی از یک فانکشن دو کار انجام میدهیم! یا یک متغیر در بیرون فانکشن تعریف میکنیم و سپس این متغیر را درون فانکشن استفاده میکنیم و تغییر میدهیم! بدین ترتیب با اتمام فانکشن، متغیر ما نیز تغییر کرده است! ولی این روش همیشه جوابگو نیست! مثلا فرض کنید یک فانکشن ۵۰۰ خطی دارید. (البته هیچ وقت نگذارید یک فانکشن در کد شما انقدر زیاد شود و آن را به بخشها و فانکشنهای کوچکتر تقسیم کنید). در خط ۲۵۰ام شرطی وجود دارد که در صورت انجام شدن آن شرط، شما قصد دارید همانجا کار فانکشن را متوقف کنید و خروجی بهدستآمده را برای ادامه کار تحویل بدهید!
مثلا در همان پروژه مدیریت رستوران فرض کنید که یک فانکشن برای محاسبه قیمت غذا داریم. این فانکشن قیمت نوشابه و قیمت غذا را جداگانه محاسبه میکند. اگر کاربر نهایی ما نوشابه سفارش نداده باشد، نیازی به محاسبه قیمت نوشابه نیست و همان قیمت غذا باید محاسبه شود. پس ما باید به نحوی بتوانیم قبل از رسیدن به بلاک مخصوص محاسبه قیمت نوشابه، قیمت نهایی را به دست بیاوریم. برای این کار از دستور return استفاده میکنیم. دستور return هر جا که استفاده شود از ادامه کار فانکشن جلوگیری میکند و هر چیزی را که روبهروی آن نوشته شده باشد، بهعنوان مقدار خروجی فانکشن برمیگرداند.
برای درک بهتر مثال زیر را ببینید.
*محتوای این قسمت تنها برای اعضای انجمن قابل مشاهده می باشد. *
اگر به نتیجه پیغام الرت نگاه کنیم، متوجه میشویم که مقدار return شده از فانکشن را به ما نشان داد. در واقع هر جا این فانکشن صدا شود، مقداری که در آن جلوی return نوشته میشود بازگردانده خواهد شد!
به مثال دیگری توجه کنید!
*محتوای این قسمت تنها برای اعضای انجمن قابل مشاهده می باشد. *
در این مثال چه اتفاقی افتاده است؟
ما یک متغیر بهعنوان سن خودمان در نظر گرفتهایم. بعد از آن یک متغیر بولین در نظر گرفتهایم که چک کنیم آیا این سن بیشتر از سی سال است یا خیر. در حالت پیشفرض ما مقدار false را به این متغیر دادهایم؛ چون فکر کردهایم که سن و سال پیشفرض کاربر ما کمتر از ۴۰ است.
سپس درون فانکشن با چک کردن سن و سال متغیر myAge گفتهایم که آیا وی سنش بیشتر از ۴۰ است یا کمتر! اگر کمتر بود isOld با مقدار false و اگر بیشتر از ۴۰ بود متغیر isOld مقدارش به true تغییر پیدا خواهد کرد! در نهایت مقدار isOld را بازگرداندهایم.
حالا در یک متغیر جدید به نام isHeOld این فانکشن را صدا کردهایم. نتیجه این کار این میشود که مقدار نهایی فانکشن isOld درون متغیر isHeOld ذخیره میشود! یعنی اگر isHeOld را صدا بزنیم عبارت true یا false به ما برگردانده خواهد شد!
حالا یک مثال دیگر خواهیم زد. در این مثال بعد از return، فانکشن ما کارهای دیگری نیز انجام میدهد! نکته مهم این تمرین این است که هر کدی که بعد از return در فانکشن نوشته میشود اجرا نخواهد شد و انگار نادیده گرفته میشود؛ چون فانکشن ما کار خود را انجام داده و مقدار لازم را به ما برگردانده است.
اگر در فانکشن اگر یک if یا else داشته باشیم که در آن return کنیم باز هم همین اتفاق میافتد.
*محتوای این قسمت تنها برای اعضای انجمن قابل مشاهده می باشد. *
در این جلسه با مفهوم توابع یا فانکشنها آشنا شدیم. ولی در آخر این جلسه میخواهیم به یک سؤال مهم برای افرادی که در ابتدای راه هستند، پاسخ دهیم.
سؤال این است که چرا باید از فانکشنها استفاده کنیم؟
سادهترین پاسخ این است که شما دیگر نیازی ندارید یک تکه کد را در ۱۰ جای مختلف بنویسید و هر بار کد تکراری را اجرا کنید. یک بار یک فانکشن برای یک کار خاص تعریف میکنید و هر وقت نیاز شد، آن را استفاده میکنید. این کار به شدت خوانایی و کارکرد کد را تحت تأثیر قرار میدهد.