Three names, three different arrows.
The words look similar but point in different directions.
__proto__ (really the hidden [[Prototype]] link) is
on every object and points to its backup object.
.prototype is only on functions and points to the object
that instances made with new will use as their backup.
.constructor is the arrow back from a prototype object to its function.
The diagram below draws all three — from live objects created on this page.
The object graph, drawn live
Pick a scenario. The boxes and arrows are computed from real objects, not hard-coded.
Prove it in this browser
Each line below was executed against the objects in the current scenario as you selected it. The pill shows the actual return value.
Open DevTools and paste any of these lines — you will get the same answers.
The rules worth memorizing
What new Foo() actually does
Three steps, no magic:
const obj = Object.create(Foo.prototype);
// 1. new object whose [[Prototype]]
// is Foo.prototype
Foo.call(obj, ...args);
// 2. run Foo with this = obj
return obj;
// 3. (unless Foo returns an object)
What instanceof actually does
It just walks the teal arrows:
obj instanceof Foo
// means: does Foo.prototype appear
// anywhere in obj's [[Prototype]] chain?
// Same as:
Foo.prototype.isPrototypeOf(obj)
class is the same machinery
A class is a constructor function with nicer syntax. extends wires two
teal arrows at once: Child.prototype → Parent.prototype for instance
methods, and Child → Parent so static members inherit too.
DOM elements play by the same rules
document.createElement("button") gives you an object whose
[[Prototype]] is HTMLButtonElement.prototype. The browser
defines the constructors; JavaScript's lookup rules do the rest. That hierarchy is
Lesson 3.