
JavaScript
Тупой вопрос по js
объясните пожалуйста поподробнее как это работает, человеческим языком а не как в учебниках )


n == true? return n*factorial(n-1)
else return 1
else return 1
а ты запусти factorial(0); и тебе единичку вернет
Можно записать факториал как:
n! = 1*...*n
А можно рекурсивно вот так:
1! = 1
n! = n*(n-1)!
Вот второй (рекурсивный) приём и используется. Функция вызывает саму себя, но с параметром, уменьшенным на 1.
n! = 1*...*n
А можно рекурсивно вот так:
1! = 1
n! = n*(n-1)!
Вот второй (рекурсивный) приём и используется. Функция вызывает саму себя, но с параметром, уменьшенным на 1.
разбей код на части, и испытай каждую на практике отдельно сам (с alert-ами), станет понятнее.
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
для остальных значений устроит рекурсию.
а чтобы понять рекурсию, нужно понять рекурсию
это то же самое, что
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 вызов функции.
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, и ошибкой это не посчитается. Вспомните об этом, когда придется жахаться с отладкой.
Похожие вопросы
- вопрос по JS. " простой ()";
- вопрос про JS, рандом чисел в %
- Небольшой вопрос по JS
- Вопрос по JS. Пожалуйста скажите почему код дает 6 пять раз. Почему не 1,2,3,4,5 .Очень запуталась от setTimeout.
- Помогите определиться с выбором нового языка (JS(TS) vs Java)
- Js фреймворки, что полезного можно для себя найти?
- В чем цель фреймворков js web?
- [HTML/CSS/JS] Как сохранять изменённые в .js данные оффлайн-сервера локально?
- Почему jQuery методы популярнее js методов при общении с ДоМ?
- ПОЧЕМУ JS ТАКОЙ НЕПОНЯТНЫЙ???
но я не понимаю откуда берется true и false