Стрелочные функции JavaScript (или arrow functions) — одно из самых заметных нововведений ES6. Выглядят лаконично, встречаются везде, и поначалу могут сбивать с толку. Разберём их от простого к сложному: как написать, когда использовать, а главное — когда лучше не стоит.
Как писали функции до ES6
В классическом JavaScript функцию объявляют с помощью ключевого слова function . Например, функция, умножающая число на 5:
function multiplyByFive(num) {
return num * 5;
} Можно записать в переменную — это называется функциональным выражением:
const multiplyByFive = function(num) {
return num * 5;
}; Ваша первая стрелочная функция
Стрелочная функция ES6 — это то же функциональное выражение, только без слова function . Вместо него ставим стрелку => после параметров:
const multiplyByFive = (num) => {
return num * 5;
}; Уже короче. Но это только начало — синтаксис можно упростить ещё сильнее.
Убираем лишние скобки
Если параметр один — круглые скобки вокруг него необязательны. Если параметров нет или их несколько, скобки нужны.
// один параметр — скобки необязательны
const multiplyByFive = num => {
return num * 5;
};
// ноль параметров — скобки нужны
const greet = () => {
return 'Привет!';
};
// два параметра — скобки нужны
const add = (a, b) => {
return a + b;
}; Неявный return
Если тело функции — одно выражение, можно убрать фигурные скобки и ключевое слово return . Значение вернётся автоматически:
const multiplyByFive = num => num * 5;
const add = (a, b) => a + b;
const greet = () => 'Привет!'; Это называется implicit return — неявный возврат. Код становится чистым и читаемым. Его часто используют с методами массивов.
Неявный return работает только когда всё тело функции — одно выражение. Если нужны несколько строк или переменные — фигурные скобки обязательны.
Осторожно: возврат объекта
Здесь есть один неочевидный момент. Если хотите вернуть объект через неявный return, фигурные скобки объекта нужно обернуть в круглые — иначе JavaScript решит, что это тело функции, а не объект:
// ❌ Так не работает — JS думает, что { name } это тело функции
const getUser = id => { name: 'Ivan' };
// ✅ Оборачиваем объект в круглые скобки
const getUser = id => ({ name: 'Ivan' }); Стрелочные функции в map, filter и других методах массивов
Пожалуй, именно здесь стрелочные функции раскрываются лучше всего. Методы массивов принимают функцию-колбэк — и запись получается очень компактной.
map — преобразует каждый элемент массива:
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(num => num * 2);
// [2, 4, 6, 8, 10] filter — отбирает элементы по условию:
const numbers = [1, 2, 3, 4, 5];
const evens = numbers.filter(num => num % 2 === 0);
// [2, 4] find — возвращает первый элемент, который прошёл условие:
const users = [
{ id: 1, name: 'Ivan' },
{ id: 2, name: 'Anna' },
];
const user = users.find(u => u.id === 2);
// { id: 2, name: 'Anna' } reduce — сворачивает массив в одно значение (например, сумму):
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, num) => acc + num, 0);
// 15 Стрелочные функции и this: главное отличие
Вот здесь кроется самая важная разница между обычными функциями и стрелочными. У стрелочной функции нет собственного this — она берёт его из окружающего контекста. Звучит абстрактно, поэтому смотрим на пример.
Классическая проблема: таймер внутри объекта. С обычной функцией this внутри setInterval указывает не на объект, а на window :
const timer = {
seconds: 0,
start: function() {
setInterval(function() {
this.seconds++; // ❌ this — это window, не timer
console.log(this.seconds); // NaN
}, 1000);
}
}; Стрелочная функция решает эту проблему элегантно — она захватывает this из метода start , то есть из объекта timer :
const timer = {
seconds: 0,
start: function() {
setInterval(() => {
this.seconds++; // ✅ this — это timer
console.log(this.seconds); // 1, 2, 3...
}, 1000);
}
}; Когда стрелочные функции не подходят
Стрелочные функции — не универсальная замена обычным. Есть три ситуации, где их использование сломает поведение.
Метод объекта. Если метод должен обращаться к свойствам объекта через this , стрелочная функция не подойдёт — this окажется window или undefined :
const user = {
name: 'Ivan',
// ❌ this.name — undefined
greet: () => `Привет, ${this.name}!`,
// ✅ this.name — 'Ivan'
greet: function() { return `Привет, ${this.name}!`; }
}; Обработчик событий. В обработчиках DOM-событий this традиционно указывает на элемент, который вызвал событие. Стрелочная функция это нарушает:
const button = document.querySelector('button');
// ❌ this — это window, не кнопка
button.addEventListener('click', () => {
this.classList.toggle('active');
});
// ✅ this — это button
button.addEventListener('click', function() {
this.classList.toggle('active');
}); Конструктор. Стрелочную функцию нельзя вызвать через new — JavaScript выбросит ошибку. Для создания объектов через конструктор используйте обычную функцию или класс:
// ❌ TypeError: Person is not a constructor
const Person = (name) => {
this.name = name;
};
const ivan = new Person('Ivan');
// ✅ Класс — правильный выбор
class Person {
constructor(name) {
this.name = name;
}
}
const ivan = new Person('Ivan'); Итого
Стрелочные функции делают код короче и чище — особенно в колбэках и методах массивов. Главное помнить два правила:
- Нет собственного this — берут из внешнего контекста
- Нельзя использовать как конструктор
В методах объектов и обработчиках DOM-событий — обычная функция надёжнее. В колбэках, цепочках методов, асинхронном коде — arrow function в JS почти всегда лучший выбор.