Стрелочные функции

функции≈ 6 минут

Здесь будет встроен видео-разбор темы (5–7 минут, YouTube / RuTube / VK Видео) — тем, кто лучше воспринимает на слух, текст ниже не обязателен.

Стрелочная функция — это не просто способ сэкономить слово function. Это отдельный вид функции: короче в записи, удобнее в коллбэках и с принципиально другим отношением к this.

Разделы темы:·

В обычном функциональном выражении половина символов — обязательная церемония: слово function, круглые скобки, фигурные скобки, return. Стрелочная запись оставляет только суть: параметры, стрелку => и тело.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Обратите внимание: стрелка всегда пишется в переменную. Объявления вида arrow name() {} не существует — стрелка это выражение, поэтому её нужно куда-то положить. Скобки вокруг единственного параметра можно опустить, но многие команды договариваются писать их всегда, чтобы строки выглядели одинаково.

Сколько параметровЧто со скобкамиПример
Ни одногопустые скобки обязательны() => 42
Одинскобки можно опуститьn => n * 2
Два и большескобки обязательны(a, b) => a + b

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

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Начинающие часто пишут фигурные скобки по привычке, но забывают return. Ошибки не будет — будет тихое undefined, которое потом ищут полчаса.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Из этого правила вытекает единственная по-настоящему неочевидная деталь стрелок. Мы хотим вернуть объектный литерал { name: name }, а движок видит открывающую фигурную скобку и решает, что это тело функции. Лечится обёрткой в круглые скобки: они говорят «дальше выражение».

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Круглые скобки вокруг объекта — не украшение и не стиль. Это способ сказать движку: то, что дальше, — выражение, а не блок кода.

Стрелки придумали ради коллбэков — функций, которые передают внутрь другой функции; им посвящена следующая статья, «Колбэки: функция как аргумент». Такой функции почти никогда не нужно имя, живёт она одну строку, и слово function в ней только мешает читать главное: что именно делают с элементом.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.
js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

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

Главное отличие стрелок от обычных функций вообще не про синтаксис. У обычной функции есть собственное this, которое зависит от того, как её вызвали. У стрелки его нет: она просто смотрит наружу, в тот код, где была написана, и берёт this оттуда.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

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

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Вместе с this стрелка лишилась псевдомассива arguments и возможности быть конструктором: new с ней выбросит ошибку. Для списка аргументов используйте остаточные параметры (...args) => ..., а для конструкторов — class или обычную функцию.

  • Стрелка — это функциональное выражение в короткой записи: параметры, знак =>, тело. Ей нужна переменная, объявления вроде function она не имеет.
  • Если после стрелки идёт выражение, оно возвращается само. Фигурные скобки превращают тело в обычный блок, и там нужен return.
  • Объект возвращают в круглых скобках: (x, y) => ({ x, y }). Без них скобка объекта читается как начало тела функции.
  • Стрелки идеальны для коллбэков в map, filter, sort и таймерах. Крупную именованную логику удобнее оставить обычной функции.
  • Своего this у стрелки нет — она берёт его из окружающего кода. Поэтому она отлично работает внутри метода и плохо подходит на роль самого метода.

1/3Что выведет console.log(f(3)) для функции const f = (n) => { n + 1 };

2/3Как записать стрелку, которая возвращает объект { ok: true }?

3/3Какое утверждение о this в стрелочной функции верно?

Переписать функции стрелками

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

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Короткая функция помещается в одно выражение, поэтому return ей не нужен. У второй тело осталось блоком — там две инструкции, значит return обязателен.

jsлистинг · не запускается
Листинг только для чтения: этот код не запускается в браузере.

Типичная ошибка здесь — записать первую функцию как (n) => { n * 3 } и получить undefined.

Стрелка, которая возвращает объект

Напишите стрелочную функцию makePoint, которая принимает x и y и возвращает объект с этими полями. Уложитесь в одну строку — без фигурных скобок в теле и без return.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Объектный литерал заворачиваем в круглые скобки, иначе движок примет его за тело функции. Имена свойств совпадают с именами параметров, поэтому годится короткая запись { x, y }.

jsлистинг · не запускается
Листинг только для чтения: этот код не запускается в браузере.

Без круглых скобок функция вернула бы undefined, и обращение к .y упало бы с ошибкой.