← Назад к вопросам

Является ли this ссылкой на объект в котором вызывается функция?

2.0 Middle🔥 231 комментариев
#JavaScript Core

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI7 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Развёрнутый ответ о this в JavaScript

Короткий ответ: нет, this не всегда является ссылкой на объект, в котором вызывается функция. Поведение this в JavaScript определяется не местом объявления функции, а способом и контекстом её вызова.

Ключевое правило

Значение this (контекст выполнения) определяется в момент вызова функции, а не в момент её объявления. Это фундаментальное отличие JavaScript от многих других языков программирования.

Основные сценарии поведения this

1. Вызов функции как метода объекта

Когда функция вызывается как метод объекта, this ссылается на этот объект:

const user = {
  name: 'Алексей',
  greet() {
    console.log(`Привет, меня зовут ${this.name}`);
  }
};

user.greet(); // this = user, выведет "Привет, меня зовут Алексей"

2. Обычный вызов функции (не как метода)

При обычном вызове функции this ссылается на глобальный объект (window в браузере, global в Node.js) или undefined в строгом режиме:

function showThis() {
  console.log(this);
}

showThis(); // В браузере: window, в строгом режиме: undefined

3. Конструктор с new

При вызове функции с оператором new, this ссылается на вновь созданный объект:

function User(name) {
  this.name = name;
  this.greet = function() {
    console.log(`Привет, я ${this.name}`);
  };
}

const user1 = new User('Мария');
user1.greet(); // this = user1, выведет "Привет, я Мария"

4. Явная привязка с call, apply, bind

Можно явно указать значение this:

function introduce(age, city) {
  console.log(`Меня зовут ${this.name}, мне ${age} лет, из ${city}`);
}

const person = { name: 'Иван' };

// call и apply вызывают функцию с указанным this
introduce.call(person, 30, 'Москва');
introduce.apply(person, [30, 'Москва']);

// bind создаёт новую функцию с привязанным this
const boundIntroduce = introduce.bind(person, 30);
boundIntroduce('Москва');

5. Стрелочные функции

Стрелочные функции не имеют своего this. Они наследуют this из окружающего лексического контекста:

const obj = {
  name: 'Объект',
  regularFunc: function() {
    console.log('Обычная функция:', this.name);
    
    const arrowFunc = () => {
      console.log('Стрелочная функция:', this.name);
    };
    
    arrowFunc();
  }
};

obj.regularFunc();
// Обычная функция: Объект
// Стрелочная функция: Объект (наследует this из regularFunc)

Проблемный случай, демонстрирующий сложность

Рассмотрим классическую проблему потери контекста:

const calculator = {
  value: 5,
  double: function() {
    return this.value * 2;
  }
};

// Работает как метод объекта
console.log(calculator.double()); // 10

// Потеря контекста при сохранении ссылки на метод
const doubleFunc = calculator.double;
console.log(doubleFunc()); // NaN (this = undefined/window)

Практические рекомендации

  1. Используйте стрелочные функции для сохранения контекста, особенно в колбэках:
class Timer {
  constructor() {
    this.seconds = 0;
    // Стрелочная функция сохраняет контекст класса
    this.timerId = setInterval(() => {
      this.seconds++;
      console.log(this.seconds);
    }, 1000);
  }
}
  1. Применяйте bind для методов, которые передаются как колбэки:
class Component {
  constructor() {
    this.handleClick = this.handleClick.bind(this);
  }
  
  handleClick() {
    console.log('Clicked:', this);
  }
}
  1. Используйте поля классов с стрелочными функциями в современных классах:
class ModernComponent {
  handleClick = () => {
    console.log('Clicked:', this);
  };
}

Вывод

this в JavaScript — это динамическая ссылка, которая определяется в момент вызова функции, а не статическая ссылка на объект, содержащий функцию. Понимание этого механизма критически важно для написания корректного JavaScript-кода, особенно при работе с объектно-ориентированным программированием, обработчиками событий и асинхронными операциями. Современные возможности языка (стрелочные функции, поля классов) помогают управлять контекстом более предсказуемо, но глубокое понимание оригинального механизма остаётся необходимым для эффективной отладки и работы с legacy-кодом.

Является ли this ссылкой на объект в котором вызывается функция? | PrepBro