2014-12-21 2 views
1

Я новичок в JavaScript и пытаюсь понять пример из книги. Когда я пройду через этот пример, я ожидаю, что значение fac (4) будет равным 12. Это было бы результатом (4 - 1) * 4.Почему этот пример функции из Eloquent JavaScript возвращает значение 24?

Однако, когда я запускаю код из онлайн-книги (в нижней части страницы) в http://eloquentjavascript.net/00_intro.html, я получаю значение 24. Что мне здесь не хватает?

function fac(n) { 
    if (n == 0) 
    return 1; 
    else 
    return fac(n - 1) * n; 
} 
console.log(fac(4)); 

Я попытался найти ответ через Twitter и через онлайн-исследования, но не увенчался успехом. Я знаю, что я что-то пропускаю, но, похоже, не вижу этого.

+1

Воспроизвести компьютер-трассировать выполнение для каждого шага. –

+1

Это «Hello World» рекурсивных функций. ;-) На самом деле проще и намного быстрее вычислить факториал без рекурсии, но там вы идете. – RobG

+0

Никогда не освещал это в школе (получил степень в социальной работе), но я потратил около часа на это, и я думаю, что у меня это есть. Оба приведенных ниже ответа очень полезны. – JimLockwood

ответ

4

Потому что это рекурсивный.

function fac(n) { 
    if (n == 0) 
    return 1; 
    else 
    return fac(n - 1) * n; 
} 
console.log(fac(4)); 

Итак, давайте проследим его

fac(3) * 4; 
fac(2) * 3 * 4; 
fac(1) * 2 * 3 * 4; 
fac(0) * 1 * 2 * 3 * 4; 
1 * 1 * 2 * 3 * 4; 

И, конечно же, то есть 24.

3

Если вы заметили, что код, в строке 5 эта функция вызывает себя, это называется рекурсией, Узнайте больше об этом на wikipedia

Позволяет вернуться к вашему коду и высушить его, чтобы посмотреть, как это работает. позволяет придать каждой строке номер, чтобы мы могли ссылаться это

1.function fac(n) { 
2. if (n == 0) 
3. return 1; 
4. else 
5. return fac(n - 1) * n; 
6.} 
7.console.log(fac(4)); 

ваш вклад значение 4 для первого вызова позволяет называть его call A.

для значения 4 if состояния в строке 1 будет возвращать ложь, так что бы в строке 5, который снова вызывает

fac(3) * 4; 

теперь ваша функция call A приостановленное здесь и делает call B со значением 3. Результат call A еще предстоит оценить.

Теперь со значением 3 это if условие в строке 2 вернет false и код в строке 5 будет выполнен, как указано выше; т.е.

fac(2) * 3; 

call B остановился здесь и там будет call C с входом 2 той же функции.

на call C вы код возвратит false против if состояния в строке 2 поэтому он будет делать call D с вводом 1. т.е.

fac(1) * 2 

Для call Dif состояния в строке 2 возвращает истину, и ваша функция будет возвращать 1 поэтому значение call D оценивается со значением 1. Теперь замените каждый факт (n) снизу вверх и продолжайте оценивать каждый вызов.

result of call D => 1 
result of call C => fac(1) * 2 => 1 * 2 => 2 
result of call B => fac(2) * 3 => 2 * 3 => 6 
result of call A => fac(3) * 4 => 6 * 4 => 24 

Я надеюсь, что вы будете в состоянии понять, как это действительно работает, важный момент в рекурсии является условием остановки которого код имеет его в строке 2.

Вышеуказанный результат также может быть получен с использованием петель, но использование рекурсии более увлекательно.

Happy Coding :)

Смежные вопросы