this определяется способом вызова, а не местом объявления:
| вызов | this |
|---|---|
obj.method() | obj |
fn() | undefined в строгом режиме |
new Fn() | новый объект |
fn.call(ctx), fn.bind(ctx) | ctx |
| стрелочная функция | this внешней области |
Отсюда классическая ошибка: передали obj.method как колбэк — this потерялся. Решения: стрелочная функция, bind, поле класса со стрелкой.
Прототипы
У каждого объекта есть скрытая ссылка [[Prototype]]. Если свойства нет в объекте, оно ищется по цепочке прототипов. class — синтаксис над той же моделью: методы лежат в Class.prototype, extends связывает прототипы.
class Animal { speak() { return "..." } }
class Dog extends Animal { speak() { return "Гав" } }
Object.getPrototypeOf(Dog.prototype) === Animal.prototype // true
Приватные поля — #field, статические — static.