← Все вопросы

Почему this не тот внутри функции в JavaScript и как это исправить?

Задан 4 месяца назад1.1к просмотров2 ответа
10

Внутри метода объекта вызываю функцию, а this вдруг становится undefined или указывает не на объект. Особенно в обработчике события или setTimeout. Почему this теряется и как привязать его правильно?

2 ответа

15
✓ Принятый ответ — помог автору

Главное про this: в обычной функции он определяется тем, как функцию вызвали, а не где её написали. Поэтому при «отрыве» метода this слетает.

Классический пример:

const user = {
  name: 'Аня',
  greet() {
    console.log('Привет, ' + this.name);
  }
};
user.greet();              // 'Привет, Аня' — вызвали как user.greet()
const fn = user.greet;
fn();                      // 'Привет, undefined' — this потерян

То же с setTimeout и обработчиками — функция вызывается «сама по себе», this уже не объект.

Решение 1 — стрелочная функция. У стрелок нет своего this, они берут его из окружающего кода:

const user = {
  name: 'Аня',
  greetLater() {
    setTimeout(() => {
      console.log(this.name); // 'Аня' — стрелка взяла this из greetLater
    }, 1000);
  }
};
user.greetLater();

Решение 2 — bind, жёстко привязать this:

const fn = user.greet.bind(user);
fn(); // 'Привет, Аня'

Часто нужно в обработчиках:

btn.addEventListener('click', this.handleClick.bind(this));

Грабли наоборот: не делай метод объекта стрелкой, если хочешь обращаться к объекту через this — стрелка возьмёт this снаружи (часто window/undefined), а не сам объект. Для методов объекта — обычная функция, для колбэков внутри — стрелка.

5

Быстрый разбор «кто такой this» по способу вызова:

  • obj.method()this это obj.
  • func() (просто так) → this это undefined (в strict mode) или window.
  • стрелочная функция → this берётся из места объявления.
  • func.call(x) / func.bind(x)this это x.

Когда видишь «this не тот», первым делом посмотри, как именно вызывается функция. Обычно она оторвалась от объекта (передана в setTimeout/слушатель). Стрелка или bind решают почти все такие случаи.

Ваш ответ

Войдите, чтобы ответить на вопрос.