> Как работает this внутри функции-конструктора и при обычном вызове функции в JavaScript (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Kaspersky, Rutube
Стек: JavaScript
> Пример ответа
Короткий ответ
this в функции-конструкторе ссылается на новый создаваемый объект, который будет возвращён при вызове с new. При обычном вызове функции this зависит от контекста выполнения: в строгом режиме - undefined, в нестрогом - глобальный объект (window в браузере). Для стрелочных функций this лексически привязан к внешнему контексту.
Подробное объяснение
Поведение this определяется правилами привязки в JavaScript. Для функций-конструкторов, вызываемых через new, создаётся новый пустой объект, который связывается с this. Этот объект наследует прототип конструктора, и если функция не возвращает явно объект, то возвращается this.
При обычном вызове функции (без new, call, apply, bind) this определяется контекстом вызова:
- В глобальном контексте: в нестрогом режиме -
window/globalThis, в строгом -undefined - Как метод объекта:
thisссылается на объект, через который вызван метод - В обработчиках событий: элемент, на котором висит обработчик
- В стрелочных функциях:
thisзахватывается из окружающего лексического контекста и не может быть переопределён
Ключевое отличие: конструктор при вызове с new всегда создаёт новый объект, игнорируя явный возврат примитива, а обычная функция может вернуть что угодно, но this остаётся привязанным к контексту вызова.
На практике
При разработке на фронтенде важно различать эти случаи, особенно в классах и при работе с DOM. В React-компонентах на классах методы нужно биндить вручную или использовать стрелочные функции, чтобы this не терялся при передаче колбэков. В функциональных компонентах с хуками эта проблема не возникает.
Для явного контроля this используйте bind, call или apply. В современном коде предпочтительнее стрелочные функции или явное связывание через bind в конструкторе.
Пример кода
JAVASCRIPT// Функция-конструкторfunction User(name) {this.name = name;this.sayHi = function() {console.log(`Привет, ${this.name}`);};}const user = new User('Анна');user.sayHi(); // Привет, Анна// Обычная функцияfunction showThis() {console.log(this);}showThis(); // window (в нестрогом режиме)// Потеря контекстаconst method = user.sayHi;method(); // Привет, undefined (this - window)// Фикс через bindconst boundMethod = user.sayHi.bind(user);boundMethod(); // Привет, Анна// Стрелочная функцияconst obj = {name: 'Объект',regular: function() { console.log(this.name); },arrow: () => { console.log(this.name); }};obj.regular(); // Объектobj.arrow(); // undefined (this - внешний контекст)
Как отвечать на собеседовании
Начните с чёткого разделения двух случаев: конструктор и обычный вызов. Объясните механизм работы new: создание объекта, привязка прототипа, возврат. Затем опишите правила привязки для обычных функций: по умолчанию, неявная (метод объекта), явная (call/apply/bind). Упомяните стрелочные функции как исключение. Приведите пример потери контекста и способов её решения. Для уровня senior добавьте рассуждение о том, как это влияет на архитектуру приложения и выбор между классами и функциями.
Что проверяет интервьюер
- Понимание механизма
newи создания объектов - Знание четырёх правил привязки
this - Умение предсказывать значение
thisв разных сценариях - Понимание разницы между стрелочными и обычными функциями
- Способность объяснить потерю контекста и методы её предотвращения
- Умение связать теорию с практическими кейсами (React, обработчики событий)
Типичные ошибки
- Утверждение, что
thisв конструкторе всегда ссылается на глобальный объект - Игнорирование строгого режима при обсуждении обычного вызова
- Путаница между
thisв стрелочной функции и в обычной функции, объявленной внутри метода - Забывание, что
bindсоздаёт новую функцию, а не изменяет исходную - Непонимание, что при возврате примитива из конструктора возвращается
this, а не примитив - Уверенность, что
thisв обработчике события всегда ссылается на элемент - это верно только для обычных функций, не для стрелочных
> Похожие задачи по frontend
Что такое fetch в JavaScript
Для чего нужен Webpack
Что происходит при обращении к переменной var и let до объявления в JavaScript
Как организовать общение между двумя вкладками одного приложения в браузере?
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью