Основы стрелочных функций JavaScript
Стрелочные функции JavaScript: краткий синтаксис ES6, неявный возврат, параметры, возврат объектов и наследование this из окружающей области видимости.
Введение в стрелочные функции
Стрелочные функции, появившиеся в ES6 (ECMAScript 2015), — это краткий способ записи функциональных выражений в JavaScript. Они особенно удобны для коротких функций и широко используются в современных JavaScript-библиотеках и приложениях — в первую очередь в виде колбэков, передаваемых в методы массивов, таймеры и обработчики событий.
Стрелочная функция — это нечто большее, чем просто сокращённый синтаксис. Она также ведёт себя иначе, чем обычная функция, в одном важном аспекте: она не создаёт собственный this. На этой странице рассматриваются синтаксис и поведение this; для продвинутых случаев (отсутствие arguments, new, генераторы) см. Стрелочные функции: продолжение.
Базовый синтаксис
Общая форма стрелочной функции выглядит так:
let functionName = (param1, param2, ..., paramN) => expression;Это создаёт функцию, принимающую param1, param2, ..., paramN в качестве параметров и возвращающую результат выражения expression. Токен => читается как «переходит к» или просто «стрелка».
Эквивалентное традиционное функциональное выражение выглядит вот так — сравнение двух вариантов наглядно показывает, что стрелочный синтаксис опускает:
В стрелочном варианте убраны ключевое слово function, фигурные скобки и явный return. Результат при этом одинаков.
Однострочные стрелочные функции (неявный возврат)
Если тело функции состоит из одного выражения, можно опустить фигурные скобки и ключевое слово return. Значение выражения возвращается автоматически — это называется неявным возвратом:
Многострочные стрелочные функции (явный возврат)
Если тело требует нескольких инструкций, оберните его в фигурные скобки {}. При использовании скобок неявный возврат пропадает, и нужно явно написать return, если необходимо вернуть значение:
Забыть return внутри фигурных скобок — типичная ошибка новичка: в этом случае функция вернёт undefined.
Правила для скобок
Правила расстановки скобок вокруг параметров просты:
- Один параметр: скобки необязательны —
x => x * 2. - Ноль параметров: пустые скобки обязательны —
() => 42. - Два и более параметра: скобки обязательны —
(a, b) => a + b.
Возврат объектного литерала
Чтобы вернуть object с синтаксисом неявного возврата, оберните его в круглые скобки. Без них JavaScript воспринимает { как начало тела функции, а не объектного литерала — и функция просто выполняется, возвращая undefined:
Преимущества стрелочных функций
- Краткость — Стрелочные функции имеют более короткий синтаксис по сравнению с традиционными функциональными выражениями, что делает колбэки более читаемыми.
- Лексический
this— Стрелочные функции не имеют собственногоthis. Они берутthisиз окружающей (родительской) области видимости, что устраняет целый класс ошибок, связанных с потерейthisв колбэках. - Неявный возврат — При однострочном синтаксисе
returnвыполняется автоматически, делая короткие преобразования чище.
Как работает this в стрелочных функциях
Это наиболее важное отличие стрелочных функций от обычных. Обычная функция получает собственный this, определяемый способом её вызова. Стрелочная функция не имеет своего this — она ищет this в области видимости, в которой была определена. Это называется лексическим this.
Классическая проблема возникает внутри метода, который планирует выполнение колбэка. С обычной функцией this колбэка теряется; со стрелочной функцией this наследуется:
Поскольку стрелочная функция захватывает this из startArrow (где this — это объект counter), она корректно читает this.value. Обычная функция внутри setTimeout вызывается без контекста объекта, поэтому её this.value равно undefined. Подробнее о том, как определяется this в обычных методах, см. в Методы объектов, «this».
Ограничения стрелочных функций
Стрелочные функции не являются универсальной заменой для любой функции. Именно их лексический this делает их непригодными в некоторых ситуациях.
- Не подходят в качестве методов объекта — Поскольку стрелочная функция наследует
thisиз окружающей области видимости, а не из объекта, для которого она вызвана, использование её в качестве метода обычно даёт не тот результат, что ожидается. - Не могут быть конструкторами — Стрелочные функции нельзя использовать с
new; при попытке будет выброшена ошибка; они не являются конструкторами. - Нет собственного object
arguments— Внутри стрелочной функцииargumentsссылается на внешнюю область видимости, а не на аргументы, переданные стрелочной функции. Используйте rest-параметры (...args).
Практический пример проблемы с методом — this не указывает на объект:
Когда что использовать
- Используйте стрелочную функцию для коротких колбэков: методы массивов, промисы, таймеры и обработчики событий, где нужно сохранить окружающий
this. - Используйте обычную функцию, когда нужен метод, использующий
thisдля обращения к своему объекту, конструктор или доступ к objectarguments.
Практические примеры
Методы массивов
Стрелочные функции отлично проявляют себя с методами массивов, такими как map, filter и reduce, где каждый вызов — это небольшое преобразование:
Обработчики событий
Стрелочные функции удобны в обработчиках событий, особенно внутри класса или объекта, где нужно, чтобы this по-прежнему указывал на окружающий экземпляр (этот пример предназначен для браузера, поэтому запускайте его на странице, а не в консоли):
document.getElementById("myButton").addEventListener("click", () => {
console.log("Button clicked!");
});Колбэки и промисы
Они делают асинхронный код компактным при использовании в качестве колбэков:
Заключение
Стрелочные функции — универсальный, повседневно используемый инструмент современного JavaScript. Они обеспечивают краткий синтаксис, поддерживают неявный возврат для однострочных тел и — что наиболее важно — наследуют this из окружающей области видимости, что позволяет избежать распространённых ошибок с контекстом в колбэках. Они идеально подходят для методов массивов, промисов и обработчиков событий, но не для методов объектов, зависящих от собственного this, конструкторов или кода, которому нужен object arguments. Понимание того, когда какой вид функции уместен, — ключ к их грамотному применению. Продолжите изучение в разделе Стрелочные функции: продолжение, посвящённом оставшимся граничным случаям.