Перейти к содержимому
Теория · Функции · урок 1 из 10

Объявление и выражение функции

Чему вы научитесь

Чему вы научитесь:

  • отличать объявление функции от выражения функции и объяснять, почему объявление можно вызвать выше его строки;
  • предсказывать, что получат параметры, если аргументов меньше или больше, и задавать значения по умолчанию;
  • записывать короткие функции как стрелочные и не терять return в теле с фигурными скобками;
  • писать рекурсивные функции с базовым случаем и объяснять, как растёт стек вызовов.
В отсек кофемашины square(x) падает плитка 4, а в чашке под носиком лежит плитка 16

Функцию удобно представлять кофемашиной на кухне. У неё есть отсеки, есть программа и есть чашка:

  • отсеки для зёрен и воды — параметры функции;
  • то, что вы засыпаете в отсеки при запуске, — аргументы;
  • программа, по которой машина варит кофе, — тело функции;
  • напиток в чашке — значение, которое функция возвращает через return.

В JavaScript такую машину можно записать двумя способами. Давайте посмотрим на оба в одной программе:

JavaScript
console.log(square(4)); // 16

function square(x) {
    return x * x;
}

const cube = function (x) {
    return x * x * x;
};

console.log(cube(2)); // 8

Разберём по строкам:

  1. console.log(square(4)) вызывает square и печатает 16, хотя сама функция записана ниже.
  2. function square(x) { … } — функция, записанная отдельной инструкцией со словом function.
  3. const cube = function (x) { … }; — функция, записанная как значение справа от const.
  4. console.log(cube(2)) печатает 8.

Обе функции вызываются одинаково. Но первая строка удивляет: как JavaScript узнал о square раньше, чем дошёл до её текста?

Объявление функции

Объявление функции — инструкция, которая начинается со слова function и задаёт имя. Объявления функций, записанные прямо в файле, а не внутри другой функции, JavaScript готовит ещё до первой строки файла.

Представьте, что перед открытием кафе все кофемашины из списка кухни уже стоят на местах и включены. Первый посетитель может заказать кофе сразу, хотя в списке машина записана в самом конце.

Объявление поднимается целиком, вместе с телом, поэтому square можно вызвать выше её объявления. Такое поведение называют поднятием. Где именно в файле стоит такое объявление, для вызова не важно.

Выражение функции

Выражение — код со значением, как в теме 3: 2 + 3, "a" + "b", x > 0. Функция тоже может быть значением.

Выражение функции — функция, записанная там, где ожидается значение. Разберём запись cube по частям:

  • после function имени нет: имя функции даёт константа cube;
  • константа cube хранит саму функцию, как const n = 5 хранит число;
  • вызов cube(2) запускает функцию, которая хранится в константе;
  • точка с запятой после } закрывает инструкцию с const, как в const n = 5;.

Такую машину привозят на кухню в определённый момент: на строке с const. До этой строки её на кухне нет. Здесь аналогия со списком кухни заканчивается: целиком поднимается только объявление функции, а константа получает функцию лишь на своей строке.

Объявление или выражение

Объявлением обычно записывают функцию, которую вызывают из разных мест программы: её можно вызвать даже выше объявления. Выражение функции выбирают, когда функция нужна как значение — например, чтобы сохранить её в константе.

Этот вопрос часто задают на собеседовании: «Чем объявление функции отличается от выражения функции?» Ответ состоит из двух частей:

  • объявление поднимается целиком, и его можно вызвать выше по файлу;
  • выражение функции доступно только после строки, где его записали.

Частая ошибка

Выражение функции вызвали выше строки, где оно записано:

JavaScript
console.log(cube(2)); // ✗

const cube = function (x) {
    return x * x * x;
};
TEXT
ReferenceError: Cannot access 'cube' before initialization

Это сообщение Node.js и Chrome; Firefox пишет can't access lexical declaration 'cube' before initialization.

Целиком поднимаются только объявления функций. Константа cube получает функцию лишь на своей строке, а до неё обращаться к cube нельзя. Перенесите вызов ниже const или запишите функцию объявлением.

Главное

  • Объявление функции поднимается целиком, поэтому его можно вызвать выше по файлу.
  • Выражение функции в константе доступно только после строки с const.
  • Объявлением записывают функцию, которую вызывают из разных мест, а выражением — функцию, нужную как значение.

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом