Быстрое объяснение прототипного наследования в JS
Концепция прототипов, используемая в JavaScript, проста. Если объект B является прототипом объекта A, то всякий раз, когда у B есть свойство, например цвет, A унаследует тот же самый цвет, если другое не указано явно. И нам не нужно повторять всю информацию про A, которую он наследует от B.
A может наследоваться от B и B, в свою очередь, может наследоваться от C и т.д. Это называется цепочкой прототипов. Наследование работает на всей протяжённости цепочки. Например, если C указывает цвет, но ни B ни A цвет не указывают, то он унаследуется от C.
Рассмотрим пример выше. В этой прототипной структуре D, E и F наследуются от прототипа P, который, в свою очередь, наследуется от Square. P указывает оба свойства — fill (цвет заливки) и stroke (цвет рамки). Но потом D переопределяет fill, а F — stroke. Три квадрата, полученных в результате наследования и переопределения свойств, изображены слева. Например, квадрат снизу F унаследовал fill от P, но сам переопределил stroke.
Вот код, который воспроизводит структуру:
let P = Object.create(Square); P.fill = 'red'; P.stroke = 'blue'; let D = Object.create(P); let E = Object.create(P); let F = Object.create(P); D.fill = 'green'; F.stroke = 'magenta'; F.fill === 'red'; >>True
Свойства, которые определяются непосредственно объектами (как stroke у F), а не наследуются из цепочки прототипов, называются собственными свойствами.
Заметьте, что я до сих пор не упомянул слово class. Прототипирование и наследование классов это разные вещи. JavaScript, в ограниченном смысле, поддерживает классы, но только как синтаксический сахар, который не влияет на базовую структуру объектов. Классы были добавлены позже (2015), в то время как прототипное наследование лежит в основе JavaScript и останется там надолго.