Введение в программирование
Теория: Функции и ящики
Транскрипт урока
В прошлый раз мы упростили вычисление с помощью констант: мы создали константу для pi, и использовали её для вычисления площади поверхности разных планет. Таким образом мы сократили объём кода, но нам всё ещё требовалось множество повторений:
Строка кода называется инструкцией, в JavaScript инструкции должны заканчиваться точкой с запятой. Тут у нас две инструкции и нам нужно повторять всю формулу в каждой из них. Помните — мы не хотим, чтобы в наших программах что-то повторялось.
Было бы здорово, если бы у нас была какая-нибудь специфическая машина, которая вычисляет площадь поверхности любой сферы. Чтобы мы могли делать что-то подобное:
Чтобы можно было просто сказать ей: "эй, surfaceAreaCalculator, скажи мне площадь поверхности сферы с радиусом 3390" и она бы сразу давала ответ.
Отличные новости! Мы можем создавать подобные машины! Их называют функциями, их можно представить в виде чёрных ящиков. Положите что-нибудь внутрь ящика, и она выплюнет что-то другое. В данном случае ящик surfaceAreaCalculator возьмёт одно число — радиус, а выплюнет другое — площадь поверхности.
В этом примере
мы вызываем ящик surfaceAreaCalculator, даём ему 3390 и получаем ответ. Этот ответ затем сохраняется в константе surfaceOfMars.
Важно понимать разницу между определением функции и её вызовом. То, что мы только что сделали, называется вызовом — мы вызвали функцию surfaceAreaCalculator, другими словами, мы предположили, что она уже существует и использовали её.
Но она должна существовать, так что нужно создать её перед тем, как использовать. Нам нужно определить функцию surfaceAreaCalculator. Это определение функции:
Эта структура со скобками, стрелкой и фигурными скобками определяет функцию. Слово radius в скобках — то, как функция называет число, которое мы передаем в нее. Это параметр функции. Эта конкретная функция принимает один аргумент, но другие функции могут принимать больше аргументов или вообще не принимать аргументов.
Фигурные скобки создают блок. В JavaScript и других языках вы часто сталкиваетесь с блоками. Они создают группу инструкций, таким способом мы понимаем где функция начинается и заканчивается. Эта функция содержит всего одну инструкцию, она начинается с return, а дальше вы видите уже знакомую формулу.
Вы, возможно, уже догадались, что return заставляет ящик выплёвывать результат. Результат вычисления 4 * pi * radius * radius это то, что функция возвращает нам после того, как мы её вызываем.
Теперь нам нужно дать этой функции какое-нибудь название, чтобы по этому названию мы её вызывали. Мне захотелось назвать её surfaceAreaCalculator, но вы можете давать любой функции любое название. Есть определенные правила для названий: например, название не должно содержать пробелы и использовать некоторые специфические слова, как const, но в остальном и функции и константы можно называть почти как захочется.
Мы уже знаем как давать названия численным константам:
С функциями все точно также:
const, название, которое вы хотите, знак равенства и сама функция
Давайте теперь соберём всё вместе:
В верхней части — определение функции, а затем вызов функции.
Давайте заглянем внутрь коробки — что происходит, когда она вызывается с числом 3390 в качестве аргумента. return хочет возвратить результат, но он ещё не готов — в начале нужно произвести вычисление. В вычислении используется аргумент, так что вначале нужно заменить название radius на само значение, которое было передано в функцию при вызове, а затем уже выполнять умножения.
И функция возвращает число 144340776. Можно представить, что происходит снаружи, когда наша функция возвращает значение:
Теперь surfaceOfMars — это константа с конкретным числовым значением.
Давайте посмотрим на другой пример:
Эта функция принимает два числа и возвращает процент. Если вы дадите ей 40 и 80, она вернёт 50, потому что 40 это 50% от 80.
Как вы видите, когда есть несколько параметров, они разделяются запятыми.
Давайте выведем результат на экран:
Сегодня 16 декабря, и я хочу узнать, какой процент этого месяца уже прошёл. Посмотрите на код. Вначале мы напечатали строку с вопросом, а потом напечатали то, что возвращает функция percentageCalculator().
Важный момент: вызов функции может быть аргументом для других функций! Как работает функция console.log()? Она принимает аргумент и выводит его на экран. Мы использовали вызов функции percentageCalculator() КАК АРГУМЕНТ и это сработало. Почему? Потому что вначале вызывается наша функция percentageCalculator(), она возвращает результат. Затем с этим результатом как аргументом вызывается функция console.log(). В итоге результат работы percentageCalculator() выводится на экран.
Ок, я свою часть закончил. Теперь ваша очередь писать функции.
Дополнение к уроку
Способы записи функций
Кроме указанного в видео определения функции:
Существует несколько других. Например, если у вас функция-однострочник, то можно использовать сокращенный синтаксис:
Отличия от полного определения два: пропали фигурные скобки и инструкция return. Сокращенная запись функции делает возврат автоматически. Подразумевается, что внутри такой функции ровно одно выражение, которое вычисляется, и его результат сразу возвращается наружу.
Пример с двумя аргументами:
Так же можно определять функции, используя ключевое слово function:
или
Мы изучаем новый стандарт ES7 и используем стрелочные функции. Поэтому в наших курсах мы будем придерживаться такой () => {} формы записи по многим причинам. Во-первых, она лаконичнее, во-вторых, обладает одним важным свойством, которое будет изучено позже, ну а в-третьих, такой способ записи визуально стирает грань между функциями и данными, что очень пригодится нам в будущем.
Некоторые особенности такой формы записи вместо function выходят за рамки базовых курсов, вы о них узнаете в будущем. Если любопытно, то можете почитать статьи по запросу «стрелочные функции es6», например https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Functions/Arrow_functions или https://habr.com/company/mailru/blog/213455/.
Формальные и фактические параметры функции
Формальными параметрами (или просто параметрами) функции называются имена переменных
в определении функции. Например у функции const f = (a, b) => a - b; формальные параметры — это a и b.
Фактические параметры — это то, что было передано в функцию в момент
вызова. Например если предыдущую функцию вызвать так f(5, z), где const z = 8, то фактическими параметрами являются 5 и z. Результатом этого вызова будет число -3, а внутри функции на момент конкретного вызова параметр a становится равным 5, а b становится равным 8. Фактические параметры еще называют аргументами функции.
Как видите, нет никакой связи между именами формальных и фактических параметров. Более того, у фактических параметров вообще может не быть имен, как в примере выше, где мы сразу передали число 3 в функцию. Что имеет значение, так это позиция. Во время вызова функции параметры должны передаваться в правильном порядке, и только тогда функция отработает, как предполагается.
Return
Вызов оператора return приводит к изменению течения программы. Последующие инструкции никогда не будут выполнены:
Выводы
- Функции подобны специальным машинам, которые мы создаём, чтобы они выполняли что-нибудь для нас.
- Функции можно представить в виде ящиков, которые принимают что-то и что-то выплёвывают.
- Функции могут принимать аргументы.
- И могут возвращать что-то.
Вот пример определения и вызова функции:
Здесь radius — это параметр функции surfaceAreaCalculator.
Вы можете вызывать функцию и вкладывать вызов другой функции в качестве аргумента: