JavaScript: Функции и их вызов
Программирование нужно для того, чтобы выполнять самые разные операции. Иногда это простые действия, например сложение чисел или объединение строк. Но чаще это сложные процессы вроде перевода денег со счёта на счёт, оформления заказа в интернет-магазине, расчёта налогов или подготовки отчёта.
Такие операции невозможно выразить одной командой. За действием вроде «перевести деньги» могут скрываться десятки, сотни и даже тысячи строк кода: проверка баланса, списание суммы, учёт комиссии, обновление базы данных, отправка уведомления.
Чтобы управлять этим кодом и не теряться в деталях, используют функции. Функция объединяет блок кода в единое целое, прячет реализацию и позволяет сосредоточиться на смысле. Программисту достаточно вызвать функцию и доверить ей всю внутреннюю работу.
Представим функцию, которая переводит деньги с одного счёта на другой. Внутри неё может быть сотни строк кода, но мы этого не видим. Снаружи всё выглядит как одна простая команда:
transferMoney('Alice', 'Bob', 100);Эта строка вызывает функцию transferMoney(). Ей передаются отправитель Alice, получатель Bob и сумма 100.
Вот ещё несколько примеров вызова функций. У каждой своё имя и свой набор данных для работы:
// Да-да, console.log тоже функция
console.log('Хекслет!');
// Отправка письма пользователю
sendEmail('bob@example.com', 'Добро пожаловать!');
// Вычисление налога с указанной суммы
calculateTax(5000, 'Florida');
// Проверка, есть ли пользователь в системе
isRegistered('Alice');
// Получение случайного числа от 1 до 10
randomNumber(1, 10);
// Создание резервной копии базы данных
backupDatabase();В вызове функции сначала пишется её имя, затем круглые скобки. Скобки показывают, что это именно вызов — так мы понимаем, что перед нами функция, а не переменная.
Внутри скобок указываются аргументы, то есть данные, которые функция получает для работы. Их может быть несколько, один или вовсе ни одного.
Откуда берутся функции?
Одни функции встроены в язык (built-in), другие создают сами программисты.
Встроенные функции идут вместе с JavaScript, их можно использовать сразу. Пример — console.log(). Как говорят, она доступна глобально.
Функции, определяемые программистами, создаются тогда, когда нужно оформить свою логику в отдельный блок. Такую функцию можно назвать любым именем и использовать как встроенную. Мы научимся этому позже.
Кроме того, существуют функции из отдельных библиотек. Чтобы ими пользоваться, их подключают с помощью механизма импорта. Подробно импорт мы пока не разбираем — достаточно знать, что он позволяет подключить внешний набор функций.
Функция с одним параметром
Возьмём функцию length(), которая возвращает количество символов в строке. Она подключается из стандартного набора функций курса с помощью импорта:
import { length } from 'hexlet-basics/string';
const message = 'Hello!';
const count = length(message);
console.log(count); // => 6В строке 'Hello!' шесть символов, поэтому вызов length(message) вернёт число 6.
Аргумент Функция Результат
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 'Hello!' │ ──→ │ length() │ ──→ │ 6 │
└──────────┘ └──────────┘ └──────────┘Возврат значения
Возврат значения — один из ключевых принципов работы функций. Если функция возвращает значение, его можно сохранить в переменную, передать в другую функцию или использовать в вычислениях:
import { length } from 'hexlet-basics/string';
const length1 = length('Hello!'); // сохраняем результат
const length2 = length('World!');
const combinedLength = length1 + length2; // используем результат в выражении
console.log(combinedLength); // => 12Если бы функция сразу печатала результат на экран (как console.log()), мы бы увидели число, но не смогли бы использовать его дальше — прибавить, сохранить или сравнить. Именно поэтому возврат значения настолько важен: он позволяет связывать функции между собой. Так из маленьких шагов строятся большие программы.
Функция с несколькими параметрами
Некоторые функции принимают сразу несколько значений. Например, Math.pow() возводит число в степень: первый аргумент — основание, второй — показатель.
// 2 в 3-й степени: 2 * 2 * 2
console.log(Math.pow(2, 3)); // => 8
// 5 во 2-й степени: 5 * 5
console.log(Math.pow(5, 2)); // => 25По структуре вызов с несколькими аргументами не отличается от вызова с одним: то же имя функции, скобки и аргументы через запятую.
Math — встроенный в JavaScript набор функций для работы с числами. Он доступен из любого места программы. Запись Math.pow(...) пока можно читать как «длинное имя функции»: приставка Math. говорит о том, что функция принадлежит этому набору. Что на самом деле означает точка — разберём в уроках про объекты. На поведение функции это никак не влияет.
Полный список математических функций доступен в документации MDN.
Параметры и аргументы
В разговорах о функциях встречаются слова параметры и аргументы. Они связаны, но это не одно и то же.
О параметрах говорят при создании функции — это переменные внутри функции, в которые попадают переданные значения. Об аргументах говорят при вызове — это то, что мы передаём в функцию. Аргументом может быть число, переменная или любое выражение:
console.log(Math.pow(2, 3)); // => 8, аргументы — числа
const x = 2;
// аргумент может быть выражением, оно вычислится до передачи
console.log(Math.pow(x + 1, 3)); // => 27Запоминать это не обязательно, но пригодится при чтении англоязычной литературы.
Как узнавать о новых функциях
У каждой функции есть сигнатура — её «описание»: имя, список параметров и тип возвращаемого значения. Именно сигнатура позволяет понять, как пользоваться функцией, не читая её код. Например, документация MDN описывает Math.pow() так:
Math.pow(base, exponent)
Параметры
base — основание степени
exponent — показатель степени
Из сигнатуры сразу видно: функция принимает два аргумента и возвращает число. Научившись читать сигнатуры, можно работать с любой незнакомой функцией.
Всё выучить невозможно — это не нужно. Важно знать, где искать. Для JavaScript есть два основных источника:
- MDN (developer.mozilla.org) — документация по встроенным возможностям языка и браузерным API.
- Документация Node.js (nodejs.org/api) — серверная часть, функции для работы с файловой системой, сетью и т. д.
Ещё один способ — читать чужой код: любой пакет на npm открыт, и в нём часто можно найти приёмы, о которых не написано в учебниках.
Задание
Сайт проверяет, вместится ли реклама двух компаний-партнёров в одну строку. В коде определены их названия — посчитайте общее количество символов в обоих названиях с помощью функции length() и выведите на экран.
Функция уже подключена в заготовке:
import { length } from 'hexlet-basics/string';Полезное
Команда проекта находится в телеграм-сообществе. Там можно задать любой вопрос и повлиять на проект
Если вы зашли в тупик, то самое время поговорить с нашим асситентом Тота во вкладке "ИИ-помощник":
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи. В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в обратной связи нашего сообщества
Ваше упражнение проверяется по этим тестам
// @ts-check
import { expect, test, vi } from 'vitest';
test('call', async () => {
const consoleLogSpy = vi.spyOn(console, 'log');
await import('./index.js');
const firstArg = consoleLogSpy.mock.calls.join('\n');
expect(firstArg).toBe('12');
});Решение учителя откроется через:
20:00
