catObj.say() и catObj.say2() выводят meow. Стрелка в поле экземпляра захватывает this экземпляра, а стрелка в литерале objCat — внешний this, не сам objCat.
Как this работает в методах класса и обычного объекта
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 не создаёт.