__proto__
- это нестандартное расширение JavaScript (распространенное в разных интерпретаторах, но нестандартное), которое дает вам прямой доступ к прототипу позади объекта. Свойство prototype
функциональных объектов - это объект, которому будет присвоено в качестве прототипа объекта, созданного путем вызова функции через new
. Поэтому, когда вы присваиваете prototype.__proto__
, вы присваиваете прототип за объектом, который будет установлен как прототип для новых объектов, созданных функцией.
Поскольку цепочка прототипов работает так, что свойства прототипа отображаются как унаследованные свойства объекта (и это продолжается в цепочке), если вы присваиваете Dog.prototype.__proto__
, объекты, созданные Dog
, будут иметь косвенный доступ к этим свойствам по цепочке:
+-----------------+ +----------------+ +-------------------------+
| instance of Dog |----->| Dog.prototype |----->| Dog.prototype.__proto__ |
| | | | | `foo` property |
| | | | | `bar` property |
+-----------------+ +----------------+ +-------------------------+
При непосредственном присвоении Dog.prototype
экземпляры имеют более прямую ссылку:
+-----------------+ +----------------+
| instance of Dog |----->| Dog.prototype |
| | | `foo` property |
| | | `bar` property |
+-----------------+ +----------------+
(Обратите внимание, что вышеприведенное * слегка вводит в заблуждение, ссылаясь на Dog.prototype
подобным образом. Экземпляры Dog
получат прямую ссылку на объект в Dog.prototype
с того момента, когда new Dog
Если вы назначите совершенно другой объект для Dog.prototype
позже, экземпляры, которые уже существуют, будут иметь старый прототип, а новые экземпляры получат новый. Но это побочный эффект.)