Стрелочные функции
В прошлом уроке мы научились передавать функцию другой функции. Иногда её не объявляли отдельно, а писали прямо в аргументе:
repeat(3, function (i) { console.log(`Шаг ${i}`);});Такая функция нужна только здесь. Мы не собираемся сохранять её под именем или вызывать отдельно – она просто описывает действие, которое repeat должна выполнить.
В JavaScript короткие функции такого типа встречаются постоянно. Поэтому для них есть более компактная запись – стрелочная функция:
repeat(3, (i) => { console.log(`Шаг ${i}`);});Изменилась только запись переданной функции. repeat по-прежнему получает функцию в параметр action и вызывает её внутри цикла.
const double = function (x) { return x * 2;};const double = (x) => { return x * 2;};Перед нами две функции с одинаковой задачей. Вторая записана стрелочным синтаксисом. Стрелочная функция во многом используется там же, где и Function Expression: это тоже функция-значение, которую сохраняют в переменной или передают аргументом, только в более компактной записи.
У стрелочной функции нет слова function. После параметров вместо него появляется стрелка =>:
(x) => { return x * 2;}Пока её можно читать почти дословно: «получи x → выполни этот код».
Что означает =>
Слева от => – параметры функции, справа – её тело. Стрелка не «сравнивает» и не «вычисляет» сама по себе – это просто часть синтаксиса стрелочной функции.
Если после стрелки стоит одно выражение без фигурных скобок, его результат возвращается автоматически. Такая запись работает так же, как тело с return:
const double = (x) => { return x * 2;};const double = (x) => x * 2;- с фигурными скобками → обычный блок, результат возвращаем через
return; - без фигурных скобок → одно выражение, его результат вернётся автоматически.
Если действий несколько
Короткое тело удобно, пока действие одно. Если нужно сделать несколько шагов, используем обычный блок:
const shout = (text) => { const loud = text + '!!!'; return loud;};console.log(shout('Ура'));Параметры стрелочной функции пишутся перед стрелкой – как у обычной функции, в круглых скобках. Есть одно послабление: если параметр ровно один, скобки вокруг него можно не писать. Получается три случая:
| Параметров | Запись | Правило |
|---|---|---|
| нет | () => 'Привет!' | пустые круглые скобки обязательны |
| один | (x) => x * 2 | при одном параметре скобки можно убрать: x => x * 2 |
| два и больше | (a, b) => a + b | скобки обязательны |
Обе записи одного параметра – (x) и x – равнозначны. Дальше при одном параметре будем писать без скобок.
Колбэк из начала урока – теперь стрелкой с одним параметром без скобок:
repeat(3, i => { console.log(`Шаг ${i}`);});А если действие совсем маленькое, хватит короткого тела:
function repeat(n, action) { for (let i = 1; i <= n; i++) { action(i); }}repeat(3, i => console.log(`Шаг ${i}`));Здесь хорошо видно, зачем появился стрелочный синтаксис. Главное в этой строке – не сама функция, а действие «напечатать номер шага», которое мы передаём в repeat.
Слово function, фигурные скобки и служебный return могут занимать больше места, чем само действие. Стрелка позволяет оставить в центре внимания именно то, что должен сделать колбэк. Сравните, где быстрее увидеть само действие:
repeat(3, function (i) { console.log(i);});repeat(3, i => console.log(i));Стрелка – не только колбэк
Стрелочная функция не обязана быть колбэком. Её можно сохранить в переменной и использовать как обычную функцию:
const add = (a, b) => a + b;console.log(add(2, 3));Стрелочная функция – это форма записи функции. Колбэк – это роль, которую функция выполняет. Поэтому стрелку можно:
- передать другой функции как колбэк;
- сохранить в переменной и вызвать напрямую.
Не всё стоит ужимать в одну строку
Короткое тело удобно, когда выражение читается сразу. Если в вычислении много частей, лучше обычный блок: он длиннее, но понятнее:
const bill = (price, qty, discount) => { const sum = price * qty; const off = sum * discount / 100; return sum - off;};const bill = (price, qty, discount) => price * qty - price * qty * discount / 100;Что использовать в этом курсе
Теперь у нас три способа записать функцию, и все три – полноправные.
Function Declaration – отдельное объявление функции с собственным именем:
function greet() { console.log('Привет!');}Function Expression – функция создаётся как значение и сохраняется в переменной:
const greet = function () { console.log('Привет!');};Стрелочная функция – тоже функция-значение, но в более компактной записи:
const greet = () => { console.log('Привет!');};Или короче – одним выражением без фигурных скобок:
const greet = () => console.log('Привет!');Пока будем ориентироваться так:
- если функция объявляется отдельно и у неё есть своё имя – чаще используем Function Declaration;
- если нужна короткая функция-значение, особенно колбэк, – часто удобно писать стрелкой;
- Function Expression тоже остаётся обычной и правильной записью.
Позже, когда появится больше практики, выбор станет вопросом контекста и стиля кода.
// теперь вы знаете
- Стрелочная функция – тоже функция-значение, как Function Expression, только в более компактной записи:
(x) => { ... }вместоfunction (x) { ... } - Если после стрелки одно выражение без фигурных скобок, его результат возвращается автоматически
- С фигурными скобками тело – обычный блок: для результата нужен return
- Параметры: () без параметров, x или (x) для одного, (a, b) для нескольких
- Стрелка особенно удобна как колбэк, но это форма записи, а не роль: её можно сохранить в переменной и вызывать как обычную функцию
Что напечатает программа?
const double = x => x * 2;console.log(double(4));
Что напечатает программа?
const a = n => n * 10;const b = n => {n * 10;};console.log(a(5), b(5));
Какие стрелочные функции записаны корректно?
Выбери все верные варианты
Верно ли, что стрелочную функцию можно использовать только как колбэк?