A continuación se muestra un ejemplo del alcance de la función MDN. No puedo entender cómo se imprime el end: 0 y el resto de end: Esperaba que console.log("end: " + i); nunca será alcanzado.
function foo(i) { if (i < 0) return; console.log("begin: " + i); foo(i - 1); console.log("end: " + i); } foo(3);Producción:
begin: 3 begin: 2 begin: 1 begin: 0 end: 0 end: 1 end: 2 end: 3Si tuviera que escribir:
console.log("begin"); my_custom_function(1); console.log("end") Luego, console.log iniciará el registro, luego se llamará a my_custom_function , y cuando my_custom_function haya terminado, continuará donde lo dejó y console.log finalizará el registro.
Es exactamente lo mismo.
Cuando foo haya terminado, volverá a la función de llamada (que también es foo ) y continuará donde lo dejó.
El truco de toda recursividad es la condición de salida. Sin ella, la función se ejecutará para siempre o el sistema se quedará sin memoria. La condición de salida para foo es if (i < 0) return; . Ahora, debido a que javascript, al menos en este caso, se ejecuta sincrónicamente, terminará lo que esté haciendo antes de pasar a la siguiente línea de código.
La función se llama a sí misma con foo(i - 1); que a su vez se llamará a sí mismo y así sucesivamente hasta que se cumpla la condición de salida. Por lo tanto, es vital que la condición de salida se coloque antes de la llamada recursiva.
Para que esto sea más fácil de entender, considere el valor de i para cada llamada sucesiva:
foo(3) foo(2) foo(1) foo(0) // exit condition is met, ending the recursion print end 0 print end 1 print end 2 print end 3Piénsalo en bloques. A continuación, agregué cada paso mostrando los valores reales de i y sangrándolos en cada recursión. Puede ver que una vez que se realiza la recursividad, finalizará la llamada de función en cada uno de los bloques anteriores.
foo(3) { if (3 < 0) return; console.log("begin: " + 3); foo(3-1) { if (2 < 0) return; console.log("begin: " + 2); foo(2-1) { if (1 < 0) return; console.log("begin: " + 1); foo(1-1) { if (0 < 0) return; console.log("begin: " + 0); foo(0-1){ if (-1 < 0) return; // Exit recursion } console.log("end: " + 0); } console.log("end: " + 1); } console.log("end: " + 2); } console.log("end: " + 3); }