Источником путаницы здесь, как мне кажется, является разница между getPrototypeOf(a)
и a.prototype
.
a.prototype
- это прототип, который будет использоваться для создания экземпляров a
, как в new a()
. Object.getPrototypeOf(a)
возвращает прототип, который использовался для создания a
, как в a = new AClass()
.
Итак, когда вы делаете a = new AClass()
, Object.getPrototypeOf(a)
равен AClass.prototype
, прототип, который использовался для создания a
.
Object.getPrototypeOf(parent).Surname = 'Smith';
Здесь getPrototypeOf
возвращает прототип, использованный для создания{}
, что составляет Object.prototype
.Эта строка эквивалентна Object.prototype.Surname = 'Smith'
.
Object.getPrototypeOf(parentFoo).Surname = 'Smith Foo';
Здесь getPrototypeOf
возвращает прототип, использованный для создания parentFoo
, то есть function(){}
: возвращаемое значение - Function.prototype
.Эта строка эквивалентна Function.prototype.Surname = 'Smith Foo'
.
console.log(childFoo.Surname);
childFoo
- это экземпляр parentFoo
, но parentFoo.prototype
не был изменен, поэтому это пустой объект (кроме встроенных).Таким образом, childFoo.Surname
идет вверх по цепочке прототипов, заканчиваясь Object.prototype
- корнем, от которого наследуются все объекты JS.Вот где он находит свойство Surname
, которое вы определили ранее, 'Smith'
.
И если вы сделаете (function () {}).Surname
, вы увидите строку 'Smith Foo'
, потому что она была определена в Function.prototype
.
(Это может быть очень сложной частью JS, чтобы обернуть голову, так что я надеюсь, что это имеет смысл!)