Стрелочные функции и this: главное отличие
Почему стрелка «решает проблему this» — и где её, наоборот, нельзя применять.
Стрелочная функция не имеет собственного
this: она берёт его из окружающей области видимости в момент создания (лексическийthis).
Обычная функция теряет this, стрелочная — нет
Классическая боль: внутри коллбэка обычная функция теряет this. Стрелка же берёт this из метода, где она написана.
const timer = {
seconds: 5,
startRegular() {
return [1].map(function () {
// обычная функция: свой this — это НЕ timer
return this === timer;
})[0];
},
startArrow() {
return [1].map(() => this === timer)[0]; // стрелка: this === timer
},
arrowValue() {
return [1].map(() => this.seconds)[0]; // и значение доступно
},
};
console.log(timer.startRegular()); // обычная функция потеряла timer
console.log(timer.startArrow()); // стрелка сохранила timer
console.log(timer.arrowValue()); // поэтому видит seconds
Вывод:
false true 5
Стрелку нельзя использовать как метод объекта
Раз стрелка берёт this снаружи, она не годится для метода: this там будет не объект, а внешний контекст.
const obj = {
name: "Аня",
regular() { return this === obj; }, // this — это obj
arrow: () => this === obj, // this взят снаружи, не obj
};
console.log(obj.regular()); // обычный метод: this === obj
console.log(obj.arrow()); // стрелка: this это НЕ obj
Вывод:
true false
Обычный метод видит this === obj. У стрелки this взят из внешней области — это не объект-владелец, поэтому она бесполезна как метод.
call/bind не меняют this стрелки
Поскольку у стрелки нет своего this, его нельзя переопределить через call, apply или bind — они просто игнорируются.
const target = { id: 1 };
const arrow = () => this === target; // this не наш target
const regular = function () { return this === target; };
console.log(arrow.call(target)); // call стрелке не помогает
console.log(regular.call(target)); // обычной функции — помогает
Вывод:
false true
Где что применять
| Ситуация | Что выбрать |
| Метод объекта | обычная функция |
| Коллбэк внутри метода | стрелочная (берёт this метода) |
| Конструктор / new | обычная функция или class |
| Короткий map/filter | стрелочная |
Итог
- Стрелка не имеет своего
this— берёт его из места, где написана. - Это удобно в коллбэках, но делает стрелку непригодной как метод объекта.
call/apply/bindне меняютthisу стрелочной функции.
Проверьте себя
1. Откуда стрелочная функция берёт this?
AИз объекта, на котором вызвана
BИз окружающей области видимости в месте создания (лексический this)
Cthis всегда undefined
DИз глобального объекта
2. Почему стрелочную функцию не стоит использовать как метод объекта?
AОна работает медленнее
BЕё this будет не объектом, а внешним контекстом
CЕё нельзя вызвать через точку
DСтрелки нельзя класть в объект
3. Что произойдёт, если вызвать стрелочную функцию через call с новым this?
Athis изменится на переданный
Bthis не изменится — у стрелки нет своего this
CБудет ошибка
DФункция не вызовется