The source of the confusion here, I think, is the difference between getPrototypeOf(a) and a.prototype.
a.prototype is the prototype that will be used to create instances of a, like in new a().
Object.getPrototypeOf(a) returns the prototype that was used to create a, like in a = new AClass().
So, when you do a = new AClass(), Object.getPrototypeOf(a) is equal to AClass.prototype, the prototype that was used to create a.
Object.getPrototypeOf(parent).Surname = 'Smith';
Here, getPrototypeOf returns the prototype used to create {}, which is Object.prototype. This line is equivalent to Object.prototype.Surname = 'Smith'.
Object.getPrototypeOf(parentFoo).Surname = 'Smith Foo';
Here, getPrototypeOf returns the prototype used to create parentFoo, which is a function(){}: The return value is Function.prototype. This line is equivalent to Function.prototype.Surname = 'Smith Foo'.
console.log(childFoo.Surname);
childFoo is an instance of parentFoo, but parentFoo.prototype was not modified, so it is an empty object (except for builtins). Thus, childFoo.Surname goes up the prototype chain, ending up at Object.prototype—the root that all JS objects inherit from. That's where it finds the Surname property that you defined earlier, 'Smith'.
And if you do (function () {}).Surname, you'll see the 'Smith Foo' string, because it was defined on Function.prototype.
(This can be a really tricky part of JS to wrap your head around, so I hope that made sense!)
parentFoonotchildFoonew parentFoodoes something completely different thanObject.create(parentFoo)?!Object.getPrototypeOfin your examples? Especially becauseObject.getPrototypeOf(parent)isObject.prototype, and you should absolutely not modifiy that.