В чём разница между классической функцией и стрелочной
Классическая функция объявляется через ключевое слово function, а стрелочная — через синтаксис => (ES6). Главные различия: поведение this, возможность использования как конструктора, доступ к arguments и синтаксис. Стрелочные функции короче и наследуют this из внешнего контекста, но не имеют собственного this, не могут быть конструкторами и не имеют объекта arguments.
Как это работает
Синтаксис
Классическая функция может быть объявлена как function declaration или function expression:
function add(a, b) {
return a + b;
}Стрелочная функция всегда является выражением и часто записывается сокращённо:
const add = (a, b) => a + b;Если тело функции — одно выражение, можно опустить фигурные скобки и return (неявный возврат). Для многострочного тела нужны скобки и явный return.
Контекст this
У классической функции this определяется в момент вызова: зависит от того, как функция вызвана (метод объекта, обычный вызов, call/apply и т.д.). У стрелочной функции this лексический: он берётся из внешнего контекста, где функция объявлена, и не меняется при вызове.
Пример с классической функцией:
const obj = {
id: 42,
counter: function() {
setTimeout(function() {
console.log(this.id); // undefined (или глобальный объект) — this потерян
}, 1000);
}
};Пример со стрелочной функцией:
const obj = {
id: 42,
counter: function() {
setTimeout(() => {
console.log(this.id); // 42 — this унаследован от counter
}, 1000);
}
};Конструктор и new
Классические функции можно вызывать с new — они работают как конструкторы. Стрелочные функции не имеют собственного this и не могут быть конструкторами: попытка new выбросит ошибку.
function Person(name) {
this.name = name;
}
const person = new Person("Alice"); // работает
const PersonArrow = (name) => {
this.name = name;
};
// new PersonArrow("Alice") — TypeError: PersonArrow is not a constructorОбъект arguments
В классической функции доступен псевдомассив arguments со всеми переданными аргументами. В стрелочной функции arguments нет — вместо него используют rest-параметры (...args).
function classic() {
console.log(arguments.length); // 3
}
classic(1, 2, 3);
const arrow = (...args) => {
console.log(args.length); // 3
};
arrow(1, 2, 3);Пример
Типичный сценарий, где стрелочные функции удобны — колбэки и обработчики событий, когда нужно сохранить this внешнего контекста. Например, в методах объекта или классах:
class Timer {
constructor() {
this.seconds = 0;
}
start() {
setInterval(() => {
this.seconds++; // this — экземпляр Timer
}, 1000);
}
}Подводные камни
- Стрелочные функции не имеют собственного
this, поэтому их нельзя использовать как методы объекта, если нужен доступ к объекту черезthis. - Нельзя использовать
call,apply,bindдля измененияthisу стрелочной функции — они проигнорируют переданный контекст. - Стрелочные функции не имеют свойства
prototype, поэтому не подходят для конструкторов. - В стрелочных функциях нет
arguments, но rest-параметры покрывают большинство случаев. - Стрелочные функции нельзя использовать как генераторы (нет
yield).
Когда использовать
Классические функции — для конструкторов, методов, которым нужен динамический this, и для функций, использующих arguments. Стрелочные функции — для коротких колбэков, функций высшего порядка и случаев, когда нужно сохранить лексический this (например, внутри методов классов).
Коротко
- Стрелочные функции короче и не имеют собственного
this— он берётся из внешней области видимости. - Классические функции можно вызывать с
new, стрелочные — нет. - В стрелочных функциях нет
arguments, используйте...rest. - Выбирайте стрелочные функции для колбэков и сохранения контекста, классические — для конструкторов и методов с динамическим
this.
Похожие вопросы
- Расскажи про опыт работы с PostgreSQL20%
- Различие методов call apply bind20%
- Что такое макро и микро задачи20%
- В чем разница == и ===20%
- Что знаешь о различии между function expression и function declaration20%
- С какими БД работал20%
- Какие способы изоляции стилей ты знаешь20%
- Какие были обязанности в прошлом проекте20%
