It is important to remember that the object, the actual, internal prototype, which is part of the prototype chain, is not the same as the property of the prototype object. The internal prototype of the object is set by the property of the prototype constructor.
In the article, I found it most understandable when I found out that this is actually this one .
In other words, the only point in changing the prototype property of an object is that this object is a function that should be used as a constructor. In addition, there is nothing magical about it, it's just a property. Changing prototype does not change __proto__ and does not affect the prototype chain of the object.
So, going through the code:
function Foo() {}
The Foo constructor is actually a function at this point, and Function.prototype is the actual Foo, the internal prototype, or __proto__ if you do.
Foo.prototype = Foo;
This only changes the prototype property of Foo, but not the internal prototype.
Foo.constructor = Foo
This actually only sets the constructor property to Foo, it does nothing with Foo.prototype.constructor, and it does nothing with the internal prototype constructor of Foo, which instanceof checks.
Try this code sequence, I hope it will be a little clearer:
function Foo() { } ; (Foo.prototype != Function.prototype && Foo.__proto__ == Function.prototype); Foo.prototype = Foo; (Foo.prototype == Foo && Foo.__proto__ != Foo && Foo.__proto__ == Function.prototype); Foo.constructor = Foo; (Foo.constructor == Foo && Foo.prototype.constructor == Foo && Foo.__proto__.constructor != Foo);