آموزش توابع بازگشتی در جاوا اسکریپت

آموزش ساخت لودینگ page loading با css
آموزش ساخت لودینگ page loading با css
۱۳ اسفند ۱۳۹۸
توابع بازگشتی در جاوا اسکریپت

آموزش توابع بازگشتی در جاوا اسکریپت recursion function با چند مثال کاربردی

در این مقاله میخوام در مورد توابع بازگشتی در جاوا اسکریپت صحبت کنم توابع بازگشتی توابعی هستند که میتونن خودشون رو فرا‌خوانی کنند که چنین فرایندی به طور کلی «بازگشت» (recursion) نامیده می‌شود توابع بازگشتی ( recursion function ) در زبان های برنامه نویسی کاربرد های زیادی دارن و میتونن به ما کمک کنن تا از تکرار کد جلوگیری کنیم مثلا در بخش های از برنامه ما اگه نیاز باشه که روی یک فرایند یک کار تکراری انجام بدیم که این کار از یک الگوی مشترک پیروی میکنه میتونیم از توابع بازگشتی استفاده کنیم مثال معروف شو هم فک کنم همه بدونن و معمولا توی دانشگاه ها این تابع رو با این چند مثال توضیح میدن که میشه از اون برای حل سری فیبوناچی یا محاسبه فاکتوریل و … استفاده کرد.

تابع بازگشتی یا recursion function چیست ؟

اگر بخوام در یک تعریف ساده این اصطلاح رو بهتون توضیح بدم میشه گفت که اگر در تعریف بدنۀ یک فانکشن ، اون فانکشن بتونه خودش رو در داخل بدنه خودش فراخوانی کنه ، به همین سادگی ما یک فانکشن بازگشتی یا recursion نوشتیم

فقط دقت داشته باشین که در نوشتن یک تابع بازگشتی باید حتما یک شرط اتمام حلقه فراخوانی براش بزارین که بعد از درست بودن شرط یک مقداری رو برگردونه چون در این صورت ما در یک حلقه بی نهایت می افتیم و برنامه خطا میده

یک مثال ساده از توابع بازگشتی

در این مثال قبل از نوشتن تابع بازگشتی من یک تابع ساده برای نمایش اعداد n تا ۰ می نویسم که در ابتدا با روش غیر بازگشتی حلش کردم بعدش اون رو تبدیل میکنم به یک تابع بازگشتی تا بتونید از این طریق مفهوم این نوع توابع رو کامل درک کنید.
خب در ابتدا من عدد ۵ رو به تابع countDown دادم که از طریق حلقه for عدد دریافتی رو از n تا ۰ نمایش بدیم فقط توجه کنید که منظور من ازn تا ۰ اینکه اگه یک عدد رو به این تابع بدیم مثلا ۵ این تابع در هر مرحله یکی از اون کم میکنه و نمایش میده تا اینکه به صفر برسه و اون عدد رو برای ما در کنسول لاگ چاپ میکنه به کد های زیر دقت کنید:

حالا مثال بالا رو با یک تابع بازگشتی انجام میدم براتون

اگر بخوام مثال بالا رو براتون توضیح بدم من تابع رو در بار اول فقط یک بار فراخوانی کردیم و عدد ۵ رو به اون پاس دادم و در دفعات بعد این تابع رو در داخل خودش فراخوانی کردم و هر دفعه از پارامتر ورودی اون یک مقداری رو کم کردم و از یک شرط اتمام فرآیند فراخوانی تابع استفاده کردم  یعنی نکته مهم در توابع بازگشتی همین شرط اتمام فرایند فراخوانی است که باید به اون خیلی دقت کنید چون اگر این شرط نباشه تابع در یک حلقه بی نهایت می افته و برنامه با خطا مواجه می شه

یک مثال کمی پیجیده تر و البته کاربردی در صفحات وب از توابع بازگشتی

اگر بخوام این مثال رو توضیح بدم و بگم ما در شرکت مون یک مگامنو داشتیم که هر دفعه داده هاشو از یک api دریافت میکردیم در یک قسمت نیاز بود که ما با استفاده از category id در هر سطحی که باشیم بیایم و parent category های این دسته بندی رو بدست بیارم پس اینجا بود که متوجه شدم باید حتما از یک تابع بازگشتی استفاده کنم چون بدون تابع بازگشتی نمیشه این مسئله رو حل کرد.

در این مثال یک آرایه داریم که داخل این آرایه تعداد object  وجود داره که شامل مجموعه ای از دسته بندی هاست و در سه سطح می باشد اگه بخواهم بیشتر توضیح بدم ما میخوایم یک تابع بازگشتی بنویسیم که وقتی category id سطح سوم این لیست را به آن بدیم این تابع بازگشتی بیاد و متن این لیست و متن دو سطح بالای اون را هم پیدا کند و به ما بده.

فرض کنید که ما یک آرایه از دسته بندی منو های سایت مون داریم که میخوایم از طریق این آرایه منو ها و زیر منو های هر دسته بندی رو پیاده سازی کنیم من برای اینکه کاربرد توابع بازگشتی رو متوجه بشین میام و اول اون رو بدون اینکه از تابع بازگشتی استفاده کنم پیاده سازی میکنم و بعدش از طریق توابع بازگشتی همین مثال رو حل میکنم تا شما با مزایای توابع بازگشتی آشنا بشین و ببینید که چقدر از تکرار کد ها جلوگیری میکنه

فرض کنید که این ارایه همون دسته بندی های ماست که از طریق یک api دریافت کردیم و میخوایم اون رو نمایش بدیم و یا عملیات خاصی روش پیاده سازی کنیم

 

حل کردن مسئله مطرح شده بالا بدون استفاده از توابع بازگشتی :

 

 

همون طور که در بالا می بینید کدامون کمی پیچیده و تو در تو شده اگه بخوام بگم که توی این تابع چیکار کردم من تابع getTextCategory رو فراخونی کردم و ایدی سومین سطح یکی از دسته بندی ها رو بهش دادم که این تابع باید بیاد و متن یا نوشته هر دسته رو برای ما برگردونه که من از طریق forEach اومدم روی آرایه پیمایش انجام دادم و در هر مرحله مقدار ایدی رو که در آرگومان getTextCategory بهمون پاس داده شده گرفتم و با تمامی ایدی تمامی عناصر این ارایه مقایسه کردم بعدش اگه برابر بود با parent id یه بار دیگه  forEach رو روی آرایه فراخوانی کردم و بعدش به همین صورت پیش رفتم تا به اول سطح برسم که parent id هاشون برابر صفر باشه

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

تابع بالا رو این بار با استفاده از تابع بازگشتی پیاده سازی کردم :

اگه بخوام در مورد کد های بالا توضیح بدم من اومد و یک تابع به اسم  getCategoryText تعریف کردم و داخلش یک آرایه جدید تعریف کردم که بتونم در هر مرحله از اجرای تابع بازگشتی مقداری دسته بندی رو بگیره و داخل خودش ذخیره کنه و در اخر این مقدار رو برای ما return کنه

همون طوری که می بینید پیاده سازی منوی تو در تو از طریق توابع بازگشتی خیلی آسونه و اصلا پیچیده نیست و خوانایی کد رو بالا میبره ما با استفاده از تابع بازگشتی میتونیم در هر سطحی که باشیم خروجی مورد نظر مون رو دریافت کنیم یعنی اگه منوی ما n تا زیر منوی مختلف داشته باشه ما خیلی ساده از طریق تابع بازگشتی میتونیم دیتای مورد نظر مون رو دریافت کنیم

امیدوارم این مقاله برای شما مفید بوده باشه و تونسته باشم مفاهیم رو درست به شما انتقال بدم اگه سوال یا پیشنهادی  داشتین میتونید از طریق بخش نظرات یا روش های که در قسمت تماس با من براتون گذاشتم نظرات و یا پیشنهادات خودتون رو با من در میون بزارین ممنونم که تا آخر این مقاله همراه من بودین

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

18 + یک =