W3docs

Функциональные выражения в JavaScript

JavaScript предлагает несколько способов определения функций: объявления функций и функциональные выражения — ключевые концепции для разработчиков.

Введение в функциональные выражения в JavaScript

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

На этой странице рассматриваются синтаксис функциональных выражений, причины их отличия от объявлений, именованные выражения, наиболее распространённые практические применения (коллбэки, IIFE, обработчики событий, асинхронный код), а также связь всего этого с современными стрелочными функциями.

Функциональные выражения: синтаксис и использование

Что такое функциональное выражение?

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

javascript— editable

Сравните это с объявлением функции, которое начинается с ключевого слова function как самостоятельного оператора:

javascript— editable

Оба варианта создают вызываемую функцию greet, однако движок обрабатывает их в разное время — именно об этом следующий раздел.

Всплытие: ключевое отличие

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

javascript— editable
Информация

Примечание: При использовании var имя greet всплывает, но его значение равно undefined до момента присваивания, поэтому ранний вызов выбрасывает TypeError ("greet is not a function"). При использовании let или const имя находится во временной мёртвой зоне, и вы получите ReferenceError. В любом случае правило одинаково: определяйте функциональное выражение до его использования.

Характеристики функциональных выражений

  • Анонимные функции: функциональные выражения нередко бывают анонимными — у функции нет собственного имени, и к ней обращаются через переменную.
  • Хранение в переменных: функция является значением, поэтому она хранится в переменной (или в элементе array, свойстве object и т. д.).
  • Объекты первого класса: в JavaScript функции являются объектами первого класса — их можно передавать в качестве аргументов, возвращать из других функций и присваивать переменным.
  • Именованные функциональные выражения: выражение может иметь собственное имя (например, let fn = function myFunc() {}). Имя видно только внутри функции, что улучшает трассировку стека и позволяет функции вызывать саму себя.
  • Стрелочные функции: в современном коде часто используются стрелочные функции (() => {}) как более краткая форма выражения, хотя они иначе обрабатывают this.

Именованные функциональные выражения

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

javascript— editable

Практическое применение функциональных выражений

Функции обратного вызова

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

javascript— editable

IIFE (немедленно вызываемое функциональное выражение)

IIFE — это функциональное выражение, которое выполняется сразу в момент определения. Обёртывающие скобки превращают функцию в выражение, а завершающие () вызывают её немедленно. Это был классический способ создать приватную область видимости и предотвратить утечку переменных в глобальную область:

javascript— editable
Информация

Примечание: Сегодня блочные let/const и ES-модули покрывают большую часть задач, для которых использовались IIFE, поэтому в новом коде они встречаются реже — однако по-прежнему широко применяются в старых библиотеках и бандлированных скриптах.

Функциональные выражения vs объявления функций

Объявление функцииФункциональное выражение
Синтаксисfunction f() {} как самостоятельный операторlet f = function () {} внутри выражения
ВсплытиеПолностью всплывает — можно вызывать до строки объявленияНедоступна до выполнения присваивания
ИмяВсегда именованнаяЧасто анонимная (может иметь имя)
Лучше подходит дляВспомогательных функций верхнего уровня, используемых во всём файлеКоллбэков, IIFE, условных определений

Практическое правило: используйте объявление для отдельной многократно используемой функции, а выражение — когда функция является значением, которое нужно куда-то передать или определить условно.

javascript— editable

Расширенные примеры и сценарии использования

Обработка событий

В браузере функциональные выражения — естественный способ добавления обработчиков событий, поскольку функция передаётся напрямую в addEventListener:

document.getElementById('myButton').addEventListener('click', function () {
  console.log('Button clicked!');
});

Асинхронное программирование

При работе с Promise и async/await функциональные выражения предоставляют лаконичный способ передавать блоки кода. Здесь функциональное выражение обрабатывает каждое успешно разрешённое значение:

javascript— editable

Заключение

Освоение функциональных выражений в JavaScript является ключом к написанию эффективного и поддерживаемого кода. Их гибкость в сочетании с возможностями функционального программирования в JavaScript делает их незаменимым инструментом в арсенале разработчика.

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

Практика

Практика
Каковы характеристики функциональных выражений в JavaScript?
Каковы характеристики функциональных выражений в JavaScript?
Was this page helpful?