Na verdade, não é tão complicado se você trabalhar com isso passo a passo. Vamos trabalhar de dentro para fora. A ligar:
three()
sem um parâmetro significa que você está passando um valor indefinido como func. Portanto, é o mesmo que dizer:
makeNum(3, undefined)
Quando o makeNum vê que func é indefinida, ele retorna num, que é 3.
Então, reduzimos isso para:
eight(minus(3))
Agora vamos ver como
minus(3)
avalia. menos vê que o parâmetro que você forneceu é 3, então ele retorna uma função que pode aceitar um parâmetro "esquerdo" e subtrair os 3 que já fornecemos a ele. NÃO é executado. Ele fica lá, esperando para ser chamado com um parâmetro "left" para que ele possa subtrair 3 dele.
Então, reduzimos isso para:
eight(function(left){
return left - 3;
})
Agora vamos ver como isso avalia. oito é chamado com o parâmetro func sendo esta função:
function(left){
return left - 3;
}
Em seguida, passa 8 e essa função para makeNum quando diz:
makeNum(8, func)
makeNum vê que func foi fornecida (e, portanto, não é indefinida) e retorna func (num) de volta à função oito, que é o mesmo que passar:
8 - 3
de volta à função oito. A função oito recebe esse valor e depois o retorna. Então, reduzimos isso para:
5
que é registrado no console.