← Назад к вопросам
Чем отличаются стрелочные функции от обычных функций в JavaScript?
3.0 Senior🔥 161 комментариев
#DevOps и инфраструктура
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Стрелочные функции vs обычные функции в JavaScript
Это важный вопрос, так как стрелочные функции (arrow functions) — это ES6 фича, которая кардинально отличается от обычных функций. Хотя я Python разработчик, JavaScript знаю хорошо, и эти различия критичны при написании фронтенда.
Синтаксис
Обычная функция:
function add(a, b) {
return a + b;
}
const add = function(a, b) {
return a + b;
};
Стрелочная функция:
const add = (a, b) => {
return a + b;
};
// Сокращённый синтаксис (implicit return)
const add = (a, b) => a + b;
// Один параметр без скобок
const square = x => x * x;
Основное отличие: контекст this
Это самое важное отличие! Arrow functions НЕ имеют своего this, они используют this из окружающего контекста.
// Обычная функция: this зависит от способа вызова
const person = {
name: "Alice",
greet: function() {
console.log(this.name); // "Alice" если вызвать person.greet()
},
delayedGreet: function() {
setTimeout(function() {
console.log(this.name); // undefined! this != person
}, 1000);
}
};
person.greet(); // "Alice"
person.delayedGreet(); // undefined
// Arrow function: сохраняет this родителя
const person2 = {
name: "Bob",
delayedGreet: function() {
setTimeout(() => {
console.log(this.name); // "Bob" - сохранило контекст!
}, 1000);
}
};
person2.delayedGreet(); // "Bob"
Таблица отличий
| Характеристика | Обычная функция | Стрелочная функция |
|---|---|---|
| this | Зависит от вызова | Из окружающего контекста |
| arguments | Есть встроенный объект | НЕТ arguments |
| new | Можно вызвать как конструктор | НЕЛЬЗЯ вызвать как конструктор |
| prototype | Есть | НЕТ |
| super | Поддерживается | НЕЛЬЗЯ использовать |
| Синтаксис | Длинный | Краткий |
this в различных контекстах
// В методе класса - обычная функция
class Counter {
constructor() {
this.count = 0;
}
increment() {
this.count++;
}
// Проблема: setTimeout потеряет контекст
incrementLater() {
setTimeout(function() {
this.count++; // this = undefined!
}, 1000);
}
// Решение: arrow function сохраняет this
incrementLaterFixed() {
setTimeout(() => {
this.count++; // this = Counter instance
}, 1000);
}
}
arguments vs rest parameters
// Обычная функция имеет встроенный arguments
function sum() {
let total = 0;
for (let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
sum(1, 2, 3); // 6
// Arrow function НЕ имеет arguments
const sum2 = () => {
console.log(arguments); // ReferenceError!
};
// Используем rest parameters (...)
const sum3 = (...args) => {
return args.reduce((a, b) => a + b, 0);
};
sum3(1, 2, 3); // 6
Когда использовать что
Используй обычную функцию:
- Конструкторы классов
- Когда нужен собственный this
- Методы объектов (если не нужна стрелочная)
- Функции с arguments
Используй стрелочную функцию:
- Callbacks (setTimeout, map, filter)
- В классах для методов, которые нужны как callbacks
- Когда нужен this из родительского контекста
- Для коротких операций (implicit return)
Практический пример
class Todo {
constructor() {
this.items = [];
}
// Обычная функция - НЕ подходит здесь
// addLater() {
// setTimeout(function() {
// this.items.push("new"); // this = undefined
// }, 1000);
// }
// Правильно - стрелочная функция
addLater() {
setTimeout(() => {
this.items.push("new"); // this = Todo instance
}, 1000);
}
// Также правильно - bind
addLaterBind() {
setTimeout(function() {
this.items.push("new");
}.bind(this), 1000);
}
}
Выводы
Стрелочные функции — это мощный инструмент для упрощения кода и избежания проблем с this. Они идеальны для callbacks, но не подходят для конструкторов и методов, где нужен собственный контекст.