En realidad, no es tan complicado si lo superas paso a paso. Trabajemos de adentro hacia afuera. Vocación:
three()
sin un parámetro significa que está pasando un valor indefinido como func. Entonces es lo mismo que decir:
makeNum(3, undefined)
Cuando makeNum ve que func no está definido, devuelve num, que es 3.
Así que hemos reducido esto a:
eight(minus(3))
Ahora veamos como
minus(3)
evalúa minus ve que el parámetro que ha proporcionado es 3, por lo que devuelve una función que puede aceptar un parámetro "izquierdo" y restar los 3 que ya le hemos proporcionado. NO se ejecuta. Simplemente se queda allí, esperando que lo llamen con un parámetro "izquierdo" para que pueda restarle 3.
Así que hemos reducido esto a:
eight(function(left){
return left - 3;
})
Ahora veamos cómo se evalúa esto. ocho se llama con el parámetro func siendo esta función:
function(left){
return left - 3;
}
Luego pasa 8 y esta función a makeNum cuando dice:
makeNum(8, func)
makeNum luego ve que se ha proporcionado func (y por lo tanto no está indefinido) y devuelve func (num) a la función ocho, que es lo mismo que pasar:
8 - 3
volviendo a la octava función. La función ocho recibe ese valor y luego lo devuelve. Así que hemos reducido esto a:
5
que se registra en la consola.