A funkció addig hívja magát, amíg valaki le nem állítja.
A rekurzió nehézséget okozhat az új fejlesztők számára. Talán azért, mert sok erőforrás tanítja algoritmikus példákkal (Fibonacci, linkelt listák). Ez a darab remélhetőleg egy egyszerű példa segítségével világosan bemutatja a dolgokat.
Alapötlet
Rekurzió az, amikor egy funkció addig hívja magát, amíg valaki le nem állítja. Ha senki sem állítja meg, akkor örökre megismétlődik (hívja magát).
A rekurzív funkciók lehetővé teszik az egységnyi munka többszöri elvégzését. Pontosan ezt hajtjuk for/while
végre a hurkok! Néha azonban a rekurzív megoldások elegánsabb megközelítést jelentenek a probléma megoldásában.
Visszaszámlálás funkció
Hozzunk létre egy függvényt, amely visszaszámol egy adott számtól. Így fogjuk használni.
countDownFrom(5); // 5 // 4 // 3 // 2 // 1
És itt van az algoritmusunk a probléma megoldására.
- Vegyünk egy nevű paramétert
number
. Ez a kiindulópontunk. - Menj
number
lefelé,0
és naplózza az utat.
Kezdjük egy for
ciklusos megközelítéssel, majd összehasonlítjuk egy rekurzív módszerrel.
Kötelező megközelítés (hurkok)
function countDownFrom(number) { for (let i = number; i > 0; i--) { console.log(i); } } countDownFrom(5); // 5 // 4 // 3 // 2 // 1
Ez mindkét algoritmikus lépést tartalmazza.
- ✅ Vegyen egy paramétert
number
. - ✅ Log mindent
number
a0
.
Rekurzív megközelítés
function countDownFrom(number) { if (number === 0) { return; } console.log(number); countDownFrom(number - 1); } countDownFrom(5); // 5 // 4 // 3 // 2 // 1
Ez is elmúlik.
- ✅ Vegyen egy paramétert
number
. - ✅ Log mindent
number
a0
.
Tehát fogalmilag a két megközelítés ugyanaz. A munkát azonban különböző módon végzik.
A kötelező megoldás hibakeresése
Vizuálisabb példaként tegyünk debugger
bele egy ciklust a hurokba, és dobjuk be a Chrome fejlesztői eszközökbe.
function countDownFrom(number) { for (let i = number; i > 0; i--) { console.log(i); debugger; } }
Látja, hogyan használ egy extra változót i
a jelenlegi szám követésére? Amint i
csökken az iteráció , végül üt 0
és véget ér.
És a for
ciklusban megadtuk a "stop if i > 0
" -t.
Rekurzív megoldásunk hibakeresése
function countDownFrom(number) { if (number === 0) { return; } console.log(number); debugger; countDownFrom(number - 1); }
A rekurzív változatnak nincs szüksége extra változókra a haladás nyomon követéséhez. Figyeljük meg, hogy a halom funkciók ( hívás stack ) növekszik, ahogy recurse?
Ez azért van, mert minden egyes hívás countDownFrom
hozzáadódik a veremhez, táplálja azt number - 1
. Ezzel number
minden alkalommal frissítve haladunk . Nincs szükség további államra!
Ez a fő különbség a két megközelítés között.
- Az iteratív belső állapotot használ (extra változókat a számláláshoz stb.).
- A rekurzív nem, egyszerűen továbbítja a frissített paramétereket az egyes hívások között.
De honnan tudja egyik verzió, mikor kell megállni?
Végtelen hurkok
Utazásai során figyelmeztethettek téged a rettegett végtelen hurokra.
? 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?!') }
Mivel elméletileg örökké futnának, egy végtelen ciklus leállítja a programot, és valószínűleg összeomlik a böngészője. Megakadályozhatja őket, ha mindig kódol egy megállási feltételt .
✅ 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); }
Mindkét esetben naplózunk x
, növekszünk, és leállunk, amikor ez lesz 3
. Funkciónknak countDownFrom
hasonló logikája volt.
// Stop at 0 for (let i = number; i > 0; i--)
A ciklusoknak megint extra állapotra van szükségük annak meghatározásához, hogy mikor kell megállniuk. Ez az, x
és mire i
való.
Végtelen rekurzió
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!
- A hurkok extra állapotváltozókat használnak a nyomon követéshez és a számláláshoz, míg a rekurzió csak a megadott paramétereket használja.
Köszönöm, hogy elolvasta
További ilyen tartalomért látogasson el a //yazeedb.com oldalra. És kérlek, tudasd velem, mit szeretnél még látni! A DM-jeim nyitva vannak a Twitteren.
A következő alkalomig!