Прототипное наследование
Вопрос
Объясните, как устроено прототипное наследование в JavaScript.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
У каждого объекта есть ссылка `[[Prototype]]` на другой объект или `null`
Чтение свойства идёт по цепочке прототипов, запись создаёт собственное свойство
`F.prototype` становится прототипом объектов, созданных через `new F()`
Методы кладут в прототип, чтобы они были общими для экземпляров
`Object.create(proto)` создаёт объект с заданным прототипом
`class` это синтаксис поверх той же модели
Что могут спросить следом
- Чем
__proto__отличается отprototype? - Что будет, если положить массив в прототип и менять его через экземпляр?
- Как сделать наследование без классов?
Разбор
Образцовый ответ: «В JS объекты наследуют напрямую от других объектов. У каждого объекта есть скрытая ссылка на прототип, её можно получить через Object.getPrototypeOf. Когда я читаю свойство, которого нет в объекте, движок ищет его в прототипе, потом в прототипе прототипа, пока не дойдёт до null. Запись так не работает: присваивание создаёт собственное свойство и затеняет прототипное. У функций есть свойство prototype: при new F() новый объект получает его своим прототипом, поэтому методы кладут туда, и они общие для всех экземпляров. Сделать наследование вручную можно через Object.create(Parent.prototype). class и extends это удобный синтаксис над этой же моделью: методы класса лежат в prototype, а extends выстраивает цепочку и для экземпляров, и для статических методов. Типичная ловушка: изменяемые данные в прототипе, например массив, оказываются общими для всех экземпляров».
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.