Greitas „Recursion“ įvedimas „Javascript“

Funkcija vadina save tol, kol kas nors ją sustabdo.

Rekursija naujiems kūrėjams gali būti sunki. Galbūt todėl, kad daugelis šaltinių to moko naudodami algoritminius pavyzdžius („Fibonacci“, susieti sąrašai). Šis kūrinys, tikiuosi, aiškiai pristatys viską, naudodamas vieną paprastą pavyzdį.

Pagrindinė idėja

Rekursija yra tada, kai funkcija paskambina, kol kas nors ją sustabdo. Jei niekas jo nesustabdys, tai pasikartos (paskambins pats) visiems laikams.

ne-tai-yra-patrikas

Rekursinės funkcijos leidžia kelis kartus atlikti darbo vienetą. Tai yra būtent tai, ką for/whilemes galime atlikti! Tačiau kartais rekursiniai sprendimai yra elegantiškesnis būdas išspręsti problemą.

Atgalinės atskaitos funkcija

Sukurkime funkciją, kuri skaičiuoja nuo nurodyto skaičiaus. Mes jį naudosime taip.

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

Štai čia mūsų algoritmas, kaip išspręsti šią problemą.

  1. Paimkite vieną pavadintą parametrą number. Tai yra mūsų atspirties taškas.
  2. Eikite nuo numberžemyn iki 0, registruodami kiekvieną kelyje.

Pradėsime nuo forciklo metodo ir palyginsime jį su rekursiniu.

Privalomas požiūris (kilpos)

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

Šiame yra abu algoritminiai žingsniai.

  1. ✅ Paimkite vieną pavadintą parametrą number.
  2. ✅ Prisijungti viskas nuo numberiki 0.

Rekursinis požiūris

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

Šis taip pat praeina.

  1. ✅ Paimkite vieną pavadintą parametrą number.
  2. ✅ Prisijungti viskas nuo numberiki 0.

Taigi konceptualiai abu požiūriai yra vienodi. Tačiau jie darbą atlieka skirtingais būdais.

Derinkite mūsų būtiną sprendimą

Norėdami pamatyti vaizdesnį pavyzdį, įdėkime „ debuggerloop“ versiją ir meskime ją į „Chrome“ kūrėjo įrankius.

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

CountdownFrom-iteratyvus

Pažiūrėkite, kaip jis naudoja papildomą kintamąjį i, norėdamas stebėti esamą skaičių? Kai kartojate, imažėja galiausiai smūgis 0ir pabaiga.

Ir forcikle nurodėme „stop if i > 0“.

Derinamas mūsų rekursinis sprendimas

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

countdownFrom-rekursyvus

Rekursinei versijai nereikia papildomų kintamųjų, kad būtų galima stebėti jos progresą. Atkreipkite dėmesį, kaip funkcijų krūva ( skambučių krūva ) auga mums kartojantis?

Taip yra todėl, kad kiekvienas skambutis į countDownFromgrupę pridedamas, jį maitinant number - 1. Tai atlikdami mes numberkiekvieną kartą einame atnaujintais būdais. Papildomos valstybės nereikia!

Tai pagrindinis skirtumas tarp dviejų požiūrių.

  1. Iterative uses internal state (extra variables for counting, etc).
  2. Recursive does not, it simply passes updated parameters between each call.

But how does either version know when to stop?

Infinite Loops

In your travels, you may have been warned about the dreaded infinite loop.

? 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?!') } 

Since they'd theoretically run forever, an infinite loop will halt your program and possibly crash your browser. You can prevent them by always coding a stopping condition.

✅ 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); } 

In both cases we log x, increment it, and stop when it becomes 3. Our countDownFrom function had similar logic.

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

Again, loops need extra state to determine when they should stop. That's what x and i are for.

Infinite Recursion

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 // ... 

yra-tai-rekursyvus

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.

tai-jus-reikia-sustabdyti

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!
  • Kilpos naudoja papildomus būsenos kintamuosius stebėjimui ir skaičiavimui, o rekursija naudoja tik pateiktus parametrus.

nykstančios kilpos

Ačiū, kad skaitėte

Norėdami gauti daugiau tokio turinio, apsilankykite //yazeedb.com. Ir praneškite, ką dar norėtumėte pamatyti! Mano DM yra atidaryti „Twitter“.

Iki kito karto!