Μια γρήγορη εισαγωγή στην αναδρομή σε Javascript

Η συνάρτηση καλείται μέχρι να σταματήσει κάποιος.

Η αναδρομή μπορεί να είναι δύσκολη για τους νέους προγραμματιστές. Ίσως επειδή πολλοί πόροι το διδάσκουν χρησιμοποιώντας αλγοριθμικά παραδείγματα (Fibonacci, συνδεδεμένες λίστες). Αυτό το κομμάτι ελπίζουμε να εισαγάγει τα πράγματα απλά, χρησιμοποιώντας ένα απλό παράδειγμα.

Βασική ιδέα

Η επανάληψη είναι όταν μια συνάρτηση καλείται μέχρι να σταματήσει κάποιος. Εάν κανείς δεν το σταματήσει τότε θα επανεμφανιστεί (καλείται) για πάντα.

όχι-αυτό-είναι-Πάτρικ

Οι αναδρομικές λειτουργίες σάς επιτρέπουν να εκτελείτε μια μονάδα εργασίας πολλές φορές. Αυτό είναι ακριβώς που οι for/whileβρόχοι μας επιτρέπουν να πετύχουμε! Μερικές φορές, ωστόσο, οι αναδρομικές λύσεις είναι μια πιο κομψή προσέγγιση για την επίλυση ενός προβλήματος.

Λειτουργία αντίστροφης μέτρησης

Ας δημιουργήσουμε μια συνάρτηση που μετράει από έναν δεδομένο αριθμό. Θα το χρησιμοποιήσουμε έτσι.

countDownFrom(5); // 5 // 4 // 3 // 2 // 1 

Και εδώ είναι ο αλγόριθμός μας για την επίλυση αυτού του προβλήματος.

  1. Πάρτε μια παράμετρο που ονομάζεται number. Αυτό είναι το σημείο εκκίνησής μας.
  2. Μεταβείτε από numberκάτω προς τα κάτω 0, καταγράφοντας το καθένα στο δρόμο.

Θα ξεκινήσουμε με μια forπροσέγγιση βρόχου και στη συνέχεια θα τη συγκρίνουμε με μια αναδρομική.

Εντυπωσιακή προσέγγιση (βρόχοι)

function countDownFrom(number) { for (let i = number; i > 0; i--) { console.log(i); } } countDownFrom(5); // 5 // 4 // 3 // 2 // 1 

Αυτό περιέχει και τα δύο αλγοριθμικά βήματα.

  1. ✅ Πάρτε μια παράμετρο που ονομάζεται number.
  2. ✅ Σύνδεση πάντα, από numberέως 0.

Αναδρομική προσέγγιση

function countDownFrom(number) { if (number === 0) { return; } console.log(number); countDownFrom(number - 1); } countDownFrom(5); // 5 // 4 // 3 // 2 // 1 

Αυτό περνάει επίσης.

  1. ✅ Πάρτε μια παράμετρο που ονομάζεται number.
  2. ✅ Σύνδεση πάντα, από numberέως 0.

Έτσι, εννοιολογικά, οι δύο προσεγγίσεις είναι ίδιες. Ωστόσο, κάνουν τη δουλειά με διαφορετικούς τρόπους.

Αποσφαλμάτωση της επιτακτικής μας λύσης

Για ένα πιο οπτικό παράδειγμα, ας το βάλουμε debuggerστην έκδοση βρόχου και ας το ρίξουμε στα Εργαλεία προγραμματιστών Chrome

function countDownFrom(number) { for (let i = number; i > 0; i--) { console.log(i); debugger; } } 

αντίστροφη μέτρηση

Δείτε πώς χρησιμοποιεί μια επιπλέον μεταβλητή i, για να παρακολουθείτε τον τρέχοντα αριθμό; Καθώς η επανάληψη iμειώνεται, τελικά χτυπάτε 0και τερματίζετε.

Και στο forβρόχο καθορίσαμε "stop if i > 0".

Εντοπισμός σφαλμάτων της αναδρομικής μας λύσης

function countDownFrom(number) { if (number === 0) { return; } console.log(number); debugger; countDownFrom(number - 1); } 

αντίστροφη μέτρηση

Η αναδρομική έκδοση δεν χρειάζεται επιπλέον μεταβλητές για την παρακολούθηση της προόδου της. Παρατηρήστε πώς αυξάνεται ο σωρός των λειτουργιών ( στοίβα κλήσεων ) καθώς επαναλαμβάνουμε;

Αυτό συμβαίνει επειδή κάθε κλήση για countDownFromπροσθήκη στη στοίβα, τροφοδοτείται number - 1. Με αυτόν τον τρόπο περνάμε numberκάθε ενημέρωση κάθε φορά. Δεν απαιτείται επιπλέον κατάσταση!

Αυτή είναι η κύρια διαφορά μεταξύ των δύο προσεγγίσεων.

  1. Η επαναληπτική χρησιμοποιεί εσωτερική κατάσταση (επιπλέον μεταβλητές για μέτρηση, κ.λπ.).
  2. Το Recursive δεν περνά απλώς τις ενημερωμένες παραμέτρους μεταξύ κάθε κλήσης.

Αλλά πώς ξέρει κάθε έκδοση πότε να σταματήσει;

Άπειροι βρόχοι

Στα ταξίδια σας, μπορεί να έχετε προειδοποιηθεί για τον τρομερό άπειρο βρόχο.

? THIS RUNS FOREVER, BE WARNED ? while (true) { console.log('WHY DID YOU RUN THIS?!' } ? THIS RUNS FOREVER, BE WARNED ? for (i = 0;;) { console.log('WHY DID YOU RUN THIS?!') } 

Δεδομένου ότι είχαν τρέξει θεωρητικά για πάντα, ένας άπειρος βρόχος θα σταματήσει το πρόγραμμά σας και πιθανώς να καταστρέψει το πρόγραμμα περιήγησής σας. Μπορείτε να τα αποτρέψετε κωδικοποιώντας πάντα μια κατάσταση διακοπής .

✅ This does not run forever x = 0; while (x < 3) { console.log(x); x++; } ✅ This does not run forever for (x = 0; x < 3; x++) { console.log(x); } 

Και στις δύο περιπτώσεις καταγράφουμε x, αυξάνουμε και σταματάμε όταν γίνεται 3. Η countDownFromλειτουργία μας είχε παρόμοια λογική.

// Stop at 0 for (let i = number; i > 0; i--) 

Και πάλι, οι βρόχοι χρειάζονται επιπλέον κατάσταση για να καθορίσουν πότε πρέπει να σταματήσουν. Αυτό είναι xκαι τι iείναι.

Άπειρη αναδρομή

Recursion also presents the same danger. It's not hard to write a self-referencing function that'll crash your browser.

?THIS RUNS FOREVER, BE WARNED? function run() { console.log('running'); run(); } run(); // running // running // ... 

είναι-αυτό-α-αναδρομικό

Without a stopping condition, run will forever call itself. You can fix that with an if statement.

✅ This does not run forever function run(x) { if (x === 3) return; console.log('running'); run(x + 1); } run(0); // running // running // running // x is 3 now, we're done. 

Base case

This is known as the base case–our recursive countDownFrom had one.

if (number === 0) { return; } 

It's the same idea as our loop's stopping logic. Whichever approach you pick, always remember that at some point it needs to be stopped.

είναι-αυτό-εσείς-πρέπει-να-σταματήσετε

Summary

  • Recursion is when a function calls itself until someone stops it.
  • It can be used instead of a loop.
  • If no one stops it, it'll recurse forever and crash your program.
  • A base case is a condition that stops the recursion. Don't forget to add them!
  • Οι βρόχοι χρησιμοποιούν επιπλέον μεταβλητές κατάστασης για παρακολούθηση και καταμέτρηση, ενώ η αναδρομή χρησιμοποιεί μόνο τις παρεχόμενες παραμέτρους.

εξαφανισμένοι βρόχοι

Ευχαριστώ για την ανάγνωση

Για περισσότερο περιεχόμενο όπως αυτό, ανατρέξτε στη διεύθυνση //yazeedb.com. Και παρακαλώ επιτρέψτε μου να ξέρω τι άλλο θα θέλατε να δείτε! Τα DM μου είναι ανοιχτά στο Twitter.

Μέχρι την επόμενη φορά!