Как this работает в методах класса и обычного объекта

catObj.say() и catObj.say2() выводят meow. Стрелка в поле экземпляра захватывает this экземпляра, а стрелка в литерале objCat — внешний this, не сам objCat.

Короткий ответ

Что ответить на собеседовании

catObj.say() и catObj.say2() выводят meow. Стрелка в поле экземпляра захватывает this экземпляра, а стрелка в литерале objCat — внешний this, не сам objCat.

Подробный разбор

Ответ с пояснениями

Условие

Нужно предсказать, что появится в консоли при вызове методов say и say2 у экземпляра класса и у простого объекта. Учтите различия между стрелочными функциями и обычными функциями.

class Animal {
  sound = 'meow';
  say = () => {
    console.log(this.sound);
  };
  say2() {
    console.log(this.sound);
  }
}

const objCat = {
  sound: 'meow',
  say: () => {
    console.log(this.sound);
  },
  say2: function () {
    console.log(this.sound);
  }
}

const catObj = new Animal();
catObj.say();     // ?
catObj.say2();    // ?
objCat.say();   // ?
objCat.say2();  // ?

Ответ

catObj.say() и catObj.say2() выводят meow. Стрелка в поле экземпляра захватывает this экземпляра, а стрелка в литерале objCat — внешний this, не сам objCat.

В обычном браузерном script без window.sound третий вызов выводит undefined, после чего objCat.say2() печатает meow. В ES-модуле внешний this равен undefined: objCat.say() бросает TypeError, и четвёртый вызов без обработки ошибки уже не выполняется.

Обычные методы получают this от объекта слева от точки. Инициализатор поля класса выполняется для экземпляра, поэтому созданная в нём стрелка сохраняет именно его. Литерал объекта такой области this не создаёт.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее