Как определяется значение this в JavaScript? Чем стрелочные функции отличаются от обычных?
Короткий ответ
- this у обычной функции зависит от способа вызова
- Вызов через точку: this — объект перед точкой
- Простой вызов: undefined в strict mode, иначе глобальный объект
- new связывает this с создаваемым объектом
- call, apply, bind задают this явно
- Стрелочная функция берёт this из внешней области
- Потеря контекста — типичная ошибка при передаче методов
this обычной функции определяется в момент вызова по четырём правилам, а стрелочная функция собственного this не имеет и захватывает его лексически.
Как сказать вслух
пример ответаУ обычной функции this определяется не тем, где она написана, а тем, как её вызвали. Если вызвали как метод объекта — this будет этот объект, если просто как функцию — undefined в строгом режиме. Ещё this можно задать явно через call, apply или bind, а оператор new привязывает его к новому объекту. Стрелочные функции устроены иначе: своего this у них нет, они просто берут его из окружающего кода, поэтому ими удобно писать колбэки.
Подробный ответ
Основной ответ
Для обычных функций действуют четыре правила в порядке приоритета: конструктор (new) — this указывает на создаваемый объект; явная привязка (call, apply, bind) — this задан аргументом; вызов как метода (obj.fn()) — this равен объекту перед точкой; обычный вызов — undefined в strict mode (а в модулях и классах strict mode включён всегда). Классическая проблема — потеря контекста: если метод сохранить в переменную или передать как колбэк (setTimeout(obj.method, 100)), связь с объектом теряется. Решения — bind, обёртка в стрелочную функцию или поля классов со стрелками. Стрелочная функция не имеет собственных this, arguments и не может быть конструктором: this разрешается лексически, как обычная переменная из замыкания, и bind на него не влияет.
Ключевые моменты
- Четыре правила. new, явная привязка, вызов через точку, обычный вызов — проверять в этом порядке.
- Потеря контекста. Передача метода как значения разрывает связь с объектом; чинится через bind или стрелку.
- Лексический this стрелок. Стрелка захватывает this окружения при создании, и переопределить его нельзя даже через call.
- Ограничения стрелок. Стрелки не подходят для методов объектов-литералов, конструкторов и обработчиков, где нужен this элемента.
Практический контекст
Вопрос проверяют сниппетами: «что выведет obj.getName после присваивания в переменную». В реальном коде это всплывает при передаче колбэков, в обработчиках событий и в классовых компонентах старого React, где методы биндили в конструкторе. Сегодня стрелочные функции закрыли большинство болей, но понимать механику нужно — например, почему в методе объекта, записанном стрелкой, this не указывает на объект.
Частые ошибки
- Говорят, что this — «объект, в котором функция объявлена», путая с местом вызова
- Используют стрелку как метод объекта и удивляются, что this не объект
- Не знают, что bind на стрелочную функцию не действует