JavaScript

Тупой вопрос по js

объясните пожалуйста поподробнее как это работает, человеческим языком а не как в учебниках )
n == true? return n*factorial(n-1)
else return 1
Олег Ливенцов
Олег Ливенцов
472
Лучший ответ
а ты запусти factorial(0); и тебе единичку вернет
***shadow Break Danc***
***shadow Break Danc***
86 738
Можно записать факториал как:
n! = 1*...*n
А можно рекурсивно вот так:
1! = 1
n! = n*(n-1)!
Вот второй (рекурсивный) приём и используется. Функция вызывает саму себя, но с параметром, уменьшенным на 1.
ЛЗ
Лёша Забора
57 914
разбей код на части, и испытай каждую на практике отдельно сам (с alert-ами), станет понятнее.
Степан Алданов
Степан Алданов
92 464
Илья Дорожан я правильно понимаю что там присваивается значение n*factorial(n-1) если n == true и значение 1 если n == false ?
но я не понимаю откуда берется true и false
return n? n * factorial(n-1) : 1;

это то же самое, что

if(n) {
return n * factorial(n-1);
} else {
return 1;
}

if(n) срабатывает когда n != 0
то есть окончательно

if (n != 0) {
return n * factorial(n-1);
} else {
return 1;
}

то есть для нуля выдаст 1
для остальных значений устроит рекурсию.

а чтобы понять рекурсию, нужно понять рекурсию
Это тернарный оператор.

x? y : z

Если X приводится к true, тогда делаем Y, иначе Z.

В данном случае функция предназначена для работы с числами, поэтому X будет true всегда, пока не станет числом 0.
___

Рассмотрим на примере:

1) Вызвали функцию factorial(2)
2) Число 2 приводится к true, поэтому выполняется код n * factorial(n - 1). В нашем случае это 2 * factorial(1). На месте factorial(1) эта же функция вызывается снова, но с аргументом 1.

3) Из прошлого вызова вызвали функцию factorial(1)
4) Число 1 приводится к true, поэтому выполняется код n * factorial(n - 1). В нашем случае это 1 * factorial(0). На месте factorial(0) эта же функция вызывается снова, но с аргументом 0.

4) Из прошлого вызова вызвали функцию factorial(0)
5) Число 0 приводится теперь к false, поэтому просто возвращается 1.

Теперь идём в обратном направлении по цепочке вызовов.

6) Внутри функции factorial(1) мы дождались ответа от factorial(0) в выражении "1 * factorial(0)", вычислили его (получилось 1 * 1, что равно 1) и вернули ответ 1.

7) Внутри функции factorial(2) мы дождались ответа от factorial(1) (который ранее дождался factorial(0), вычисляем "2 * 1", равный 2 и возвращаем его.

Итого - factorial(2) возвращает ответ число 2.
Аналогично для любого факториала, хоть 100, только рекурсия в javascript обозначает вызов функции, не завершая предыдущую, то есть при factorial(100) в стеке вызовов будет минимум 100 вложенных вызовов одновременно и это память, которая тратится на хранение кучи сопутствующей информации.

Это и есть рекурсия - разбиение задачи (вычисление факториала) на маленькие шаги, вызывая одну и ту же функцию с разными аргументами.

И её всегда можно заменить на цикл. То есть посчитать факториал как-то так:

function factorial(n) {
let result = 1;
while (n > 0) {
result = result * n;
n--;
}
return result;
}

Менее изящно, но затраты по памяти гораздо меньше, потому что здесь только 1 вызов функции.
Лучше сначала проверить, является ли n числом. В вашем коде оно может быть true, false, null или undefined, и ошибкой это не посчитается. Вспомните об этом, когда придется жахаться с отладкой.
Фото Фото
Фото Фото
2 176