Javascript - como funcionam as funções recursivas

O que é recursão e como aplicar em JS? Como isso pode melhorar meu código? Sexta, no Globo Repórter!
Não, pera… vem comigo que eu te mostro AGORA! :D

O que é recursão?

Em desenvolvimento de software, recursão é quando você tem uma chamada para um método ou função dela para ela mesma.

Hãn?

Você já colocou um espelho em frente ao outro? A imagem de um refletindo no outro, que reflete no um, que reflete no outro, que reflete… então, isso é um exemplo de recursão :)

Quando eu devo usar funções recursivas?

Quando você precisa executar a mesma tarefa repetidas vezes, pode ser um caso onde a recursão vai ser útil.

Vamos a um exemplo bastante útil: você vai mostrar uma mensagem a cada vez que um grilo chiar. Você passa como parâmetro da função, quantas vezes você quer que aconteça o chiado, e a função retorna com a palavra chirp a cada vez.

Sem usar recursão, nossa implementação se pareceria com isso:

1
2
3
4
5
6
7
8
function chirp(n) {
var ch = 'chirp';
if( n < 1 || isNaN(n) ) return;
for( var i = n - 1; i--; ) {
ch += '-chirp';
}
return ch;
}

Invocando a função, temos como resultado:

1
chirp( 3 ); // => "chirp-chirp-chirp"

Agora, usando o formato recursivo:

1
2
3
4
function chirp( n ) {
if( n < 1 || isNaN( n ) ) return;
return n < 2 ? 'chirp' : chirp( n - 1 ) + '-chirp';
}

E a invocação traz o mesmo resultado:

1
chirp( 3 ) // => "chirp-chirp-chirp"

Se fizermos um teste de mesa, fica mais fácil entender como uma função recursiva funciona:

Valor de n Retorno da função
Invocação da função (fora) 3 n é menor 2? Não. Então invoca a função de novo e aguarda o resultado para concatenar com -chirp.
Primeira invocação recursiva 2 n é menor que 2? Não. Então invoca a função de novo e aguarda o resultado para concatenar com -chirp de agora, e o -chirp anterior.
Segunda invocação recursiva 1 n é menor que 2? Sim. Então, retorna chirp e volta com esse resultado para concatenar com os resultados anteriores que haviam ficado aguardando. Pega esse último chirp, concatena com o penúltimo -chirp, e então, concatena isso com o primeiro -chirp. Resultado final: chirp-chirp-chirp.

Você pode perceber que o resultado fica aguardando até que a última chamada recursiva seja concluída, para então concatenar os resultados. Em alguns casos, isso pode se tornar mais lento que a forma não recursiva. Mas dependendo do caso, pode se tornar mais legível, facilitando a manutenção. O uso deve ser avaliado conforme a situação.

Perceba também que, para obtermos a recursão, nós precisamos basicamente de 2 coisas:

  1. A função deve se auto-invocar, no interior dela mesma;
  2. É necessário uma verificação para que possamos concluir a recursão. Caso contrário, teremos um loop infinito!

Esse é o princípio básico da recursão :)

Espero que tenha ficado claro! Se ainda ficaram dúvidas, poste nos comentários :D

Até a próxima aventura! :D

Sobre o #1postperday: https://blog.da2k.com.br/2014/12/31/um-post-por-dia/

Tem alguma sugestão para os próximos posts do #1postperday? Deixe ela aqui: https://github.com/fdaciuk/fdaciuk.github.io/issues/1