В чем разница между стрелочной и обычной функцией в контексте this в JavaScript?
Что проверяют
Тот же корень, что и вопрос про this, но с упором на выбор: где стрелочная уместна, а где сломает поведение.
Как отвечать
Обычная функция получает this в момент вызова, по правилам вызова. Стрелочная своего this не имеет: она берёт его лексически, из области, где была создана, и изменить это нельзя.
Следствия:
call,applyиbindна стрелочной функции контекст не меняют;- стрелочную нельзя вызвать через
new: конструктором она быть не может; - у стрелочной нет
arguments(нужен остаточный параметр...args) и нетprototype.
Где стрелочная удобна: колбэки внутри методов и классов, где нужно сохранить контекст.
class Timer {
seconds = 0;
start() {
setInterval(() => { this.seconds += 1; }, 1000); // this это экземпляр
}
}С обычной функцией внутри setInterval контекст потерялся бы, и раньше это лечили через const self = this или bind.
Где стрелочная вредна:
- метод объекта, если внутри нужен сам объект;
- обработчик события, если нужен элемент (
thisв обычной функции это узел, к которому привязан обработчик); - метод прототипа, который потом планируют вызывать с другим контекстом.
Где спотыкаются
Пишут const obj = { value: 1, get: () => this.value } и получают undefined.
Считают, что стрелочная функция быстрее или «современнее», и заменяют ими всё подряд, включая методы классов, где это ломает наследование.
Не знают, что у стрелочной нет arguments, и удивляются ошибке в старом коде, переписанном механически.