при вызове в глобальном контексте: this → global/window, а в строгом режиме — undefined callback, переданный в setTimeout или setInterval, выполняется как функция без объекта-владельца контекст this внутри callback автоматически не сохраняется для привязки this применяют bind(), стрелочные функции либо внешнюю переменную setTimeout и setInterval сами по себе не выполняют связывание контекста значение this определяется способом создания callback: стрелочная лямбда сохраняет лексический this практическое следствие: без bind или стрелочной функции обращение к методу объекта из таймера часто перестаёт работать
Почему setInterval и setTimeout изменяют значение this?
при вызове в глобальном контексте: this → global/window, а в строгом режиме — undefined callback, переданный в setTimeout или setInterval, выполняется как функция без объекта-владельца контекст this внутри callback…
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Почему setInterval и setTimeout изменяют значение this?
- при вызове в глобальном контексте: this → global/window, а в строгом режиме — undefined
- callback, переданный в setTimeout или setInterval, выполняется как функция без объекта-владельца
- контекст this внутри callback автоматически не сохраняется
- для привязки this применяют bind(), стрелочные функции либо внешнюю переменную
- setTimeout и setInterval сами по себе не выполняют связывание контекста
- значение this определяется способом создания callback: стрелочная лямбда сохраняет лексический this
- практическое следствие: без bind или стрелочной функции обращение к методу объекта из таймера часто перестаёт работать
Подробный ответ
Основной ответ
В JavaScript setTimeout и setInterval запускают callback-функции после заданной задержки или с указанным интервалом. Однако контекст this внутри такого callback обычно не сохраняется: он становится глобальным объектом — в браузере это window, а в strict mode — undefined. Причина в том, что функция запускается не как метод объекта, а как обычный вызов функции.
Ключевые моменты
- Если в стандартной ситуации передать в
setTimeoutилиsetIntervalметод объекта напрямую (obj.method), значениеthisвнутри этого метода больше не указывает на исходный объект. Вместо него используется глобальный контекст либоundefinedв strict mode. - Чтобы сохранить правильный
this, применяют bind, стрелочные функции или промежуточные обёртки:js setTimeout(obj.method.bind(obj), 1000);илиjs setTimeout(() => obj.method(), 1000); - Например, в React 18+ стрелочные функции внутри таймеров считаются стандартным и безопасным паттерном, поскольку позволяют гарантировать сохранение контекста.
- Такое поведение объясняется тем, что
setTimeout/setIntervalполучают callback, который затем вызывается механизмом таймера без привязки к исходному объекту.
Практический контекст
В прикладном коде важно учитывать сохранение контекста при асинхронных вызовах. Распространённая ошибка — обращение внутри callback таймера к свойствам объекта через this; это может привести к undefined или вызвать ошибки. Для предотвращения таких проблем используют bind либо стрелочные функции, что помогает избежать багов и повысить надёжность кода.