Выразительный JavaScript | страница 30
Чтобы лучше понять, как функция достигает нужного эффекта, давайте просмотрим её вызовы, которые происходят в поисках решения для числа 13.
>find(1, "1")
> find(6, "(1 + 5)")
> find(11, "((1 + 5) + 5)")
> find(16, "(((1 + 5) + 5) + 5)")
> too big
> find(33, "(((1 + 5) + 5) * 3)")
> too big
> find(18, "((1 + 5) * 3)")
> too big
> find(3, "(1 * 3)")
> find(8, "((1 * 3) + 5)")
> find(13, "(((1 * 3) + 5) + 5)")
> found!
Отступ показывает глубину стека вызовов. В первый раз функция find вызывает сама себя дважды, чтобы проверить решения, начинающиеся с >(1 + 5)
и >(1 * 3)
. Первый вызов ищет решение, начинающееся с >(1 + 5)
, и при помощи рекурсии проверяет все решения, выдающие число, меньшее или равное требуемому. Не находит, и возвращает >null
. Тогда-то оператор >||
и переходит к вызову функции, который исследует вариант >(1 * 3)
. Здесь нас ждёт удача, потому что в третьем рекурсивном вызове мы получаем 13. Этот вызов возвращает строку, и каждый из операторов >||
по пути передаёт эту строку выше, в результате возвращая решение.
Выращиваем функции
Существует два более-менее естественных способа ввода функций в программу.
Первый – вы пишете схожий код несколько раз. Этого нужно избегать – больше кода означает больше места для ошибок и больше материала для чтения тех, кто пытается понять программу. Так что мы берём повторяющуюся функциональность, подбираем ей хорошее имя и помещаем её в функцию.
Второй способ – вы обнаруживаете потребность в некоей новой функциональности, которая достойна помещения в отдельную функцию. Вы начинаете с названия функции, и затем пишете её тело. Можно даже начинать с написания кода, использующего функцию, до того, как сама функция будет определена.
То, насколько сложно вам подобрать имя для функции, показывает, как хорошо вы представляете себе её функциональность. Возьмём пример. Нам нужно написать программу, выводящую два числа, количество коров и куриц на ферме, за которыми идут слова «коров» и «куриц». К числам нужно спереди добавить нули так, чтобы каждое занимало ровно три позиции.
>007 Коров
>011 Куриц
Очевидно, что нам понадобится функция с двумя аргументами. Начинаем кодить.
>// вывестиИнвентаризациюФермы
>function printFarmInventory(cows, chickens) {
> var cowString = String(cows);
> while (cowString.length < 3)
> cowString = "0" + cowString;
> console.log(cowString + " Коров");