Как обратиться к объекту и пройти по цепочке прототипов в JavaScript
Что проверяют
Понимаете ли вы, как движок ищет свойство: сначала в самом объекте, потом по ссылке [[Prototype]] вверх до null. Следом обычно спрашивают, чем class отличается от функции-конструктора, или просят вручную реализовать instanceof.
Как отвечать
У каждого объекта есть внутренняя ссылка [[Prototype]]. При чтении obj.x движок смотрит собственные свойства, затем прототип, затем его прототип, пока не дойдёт до Object.prototype, чей прототип null. Запись obj.x = 1 обычно создаёт собственное свойство и затеняет унаследованное, прототип не меняется (исключение: сеттер или неизменяемое свойство в цепочке).
- чтение прототипа:
Object.getPrototypeOf(obj), а__proto__оставлен ради совместимости; - создание:
Object.create(proto), в том числеObject.create(null)для словаря без унаследованных ключей; - проверки:
Object.hasOwn(obj, key)для собственных свойств,key in objдля всей цепочки,instanceofсравниваетCtor.prototypeсо звеньями цепочки; - обход:
for (let p = obj; p !== null; p = Object.getPrototypeOf(p))сObject.getOwnPropertyNames(p)на каждом шаге.for...inтоже идёт по цепочке, но видит только перечисляемые свойства, методы классов в него не попадут.
class построен на той же модели: методы лежат в Foo.prototype, а extends связывает и прототипы экземпляров, и сами конструкторы, поэтому статические методы тоже наследуются. Стоит добавить, что Object.setPrototypeOf на живом объекте ломает оптимизации движка, а расширять встроенные прототипы вроде Array.prototype в прикладном коде нельзя: такие расширения уже конфликтовали с новыми методами стандарта.
Где спотыкаются
Путают prototype функции и [[Prototype]] объекта. Первое это свойство конструктора, которое станет прототипом экземпляров, второе ссылка у любого объекта.
Проверяют собственное свойство через obj.key !== undefined или in, хотя значение может прийти из прототипа.
Думают, что присваивание в экземпляре меняет общий метод у всех. Оно создаёт собственное свойство. А вот мутация массива или объекта, лежащего в прототипе, видна всем экземплярам сразу.