> Как работает 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)
// Фикс через bind
const 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 в обработчике события всегда ссылается на элемент - это верно только для обычных функций, не для стрелочных

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью