Reputation: 410
The code below is what I test in browser.
function A(){}
a = new A()
a.__proto__ === a //false
a.__proto__.constructor === a.constructor //true
It's confusing for me why a.__proto__
and a
share the same .constructor
Upvotes: 0
Views: 60
Reputation: 1073998
a.__proto__ === a
is false because a
is not its own prototype. They're separate objects
a.__proto__.constructor === a.constructor
is true because the a
object inherits the constructor
property from its prototype. So you can access the property on a
(indirectly) or on its prototype.
When you do a = new A()
, here's a rough idea of what you have in memory (handwaving away some details), which may help:
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ | | | +−−−−−−−−−−−−−−−+ | A−−−−+−>| (function) | | +−−−−−−−−−−−−−−−+ | | name: "A" | +−−−−−−−−−−−−−−−+ | | prototype |−−−−−−−−−−−−−−−−−−−−−+−>| (object) | | | [[Prototype]] |−>Function.prototype | +−−−−−−−−−−−−−−−+ | | [[Code]] | | | constructor |−+ +−−−−−−−−−−−−−−−+ | | [[Prototype]] |−>Object.prototype | +−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−+ | a−>| (object) | | +−−−−−−−−−−−−−−−+ | | [[Prototype]] |−−−−−−−−−−−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−+
([[Prototype]]
is a link to the object's prototype, the value returned by the deprecated __proto__
and by the modern Object.getPrototypeOf()
. Also: Function.prototype
's prototype is Object.prototype
, not shown above.)
A
is a constructor function. It has a property, prototype
, which points to the object that will be used as the prototype of objects created via new A
. a
is an object created via new A
, so its prototype ([[Prototype]]
) is that same object. The A.prototype
object has a property, constructor
, that refers back to the constructor function it's associated with (in the simple, default case).
It becomes a bit more useful when you have two instances, a1
and a2
. Let's modify the code a bit:
// Part 1
function A(foo) {
this.foo = foo;
}
A.prototype.method = function() {
console.log(this.foo);
};
// Part 2
const a1 = new A("one");
const a2 = new A("two");
a1.method(); // "one"
a2.method(); // "two"
After Part 1 above runs, we have something like this (again, leaving out some details, and I've used Fp
and Op
instead of Function.prototype
and Object.prototype
to save space):
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ | | | +−−−−−−−−−−−−−−−+ | A−−−−+−>| (function) | | +−−−−−−−−−−−−−−−+ | | name: "A" | +−−−−−−−−−−−−−−−+ | | prototype |−−−−−>| (object) | | | [[Prototype]] |−>Fp +−−−−−−−−−−−−−−−+ | | [[Code]] | | constructor |−+ +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−+ | method |−−−−−>| (function) | | [[Prototype]] |−>Op +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−+ | name: "method" | | [[Prototype]] |−>Fp | [[Code]] | +−−−−−−−−−−−−−−−−+
After the const a1 = new A("one");
line, we have:
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ | | | +−−−−−−−−−−−−−−−+ | A−−−−+−>| (function) | | +−−−−−−−−−−−−−−−+ | | name: "A" | +−−−−−−−−−−−−−−−+ | | prototype |−−−−−−+−>| (object) | | | [[Prototype]] |−>Fp | +−−−−−−−−−−−−−−−+ | | [[Code]] | | | constructor |−+ +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−+ | | method |−−−−−>| (function) | | | [[Prototype]] |−>Op +−−−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−−+ | name: "method" | | | [[Prototype]] |−>Fp | | [[Code]] | | +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−+ | a1−−>| (object) | | +−−−−−−−−−−−−−−−+ | | foo: "one" | | | [[Prototype]] |−−−−−−−−−+ +−−−−−−−−−−−−−−−+
After the const a2 = new A("two");
line, we have:
+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−+ | | | +−−−−−−−−−−−−−−−+ | A−−−−+−>| (function) | | +−−−−−−−−−−−−−−−+ | | name: "A" | +−−−−−−−−−−−−−−−+ | | prototype |−−−−−−+−>| (object) | | | [[Prototype]] |−>Fp | +−−−−−−−−−−−−−−−+ | | [[Code]] | | | constructor |−+ +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−+ | | method |−−−−−>| (function) | | | [[Prototype]] |−>Op +−−−−−−−−−−−−−−−−+ | +−−−−−−−−−−−−−−−+ | name: "method" | | | [[Prototype]] |−>Fp | | [[Code]] | | +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−+ | a1−−>| (object) | | +−−−−−−−−−−−−−−−+ | | foo: "one" | | | [[Prototype]] |−−−−−−−−−+ +−−−−−−−−−−−−−−−+ | | +−−−−−−−−−−−−−−−+ | a2−−>| (object) | | +−−−−−−−−−−−−−−−+ | | foo: "two" | | | [[Prototype]] |−−−−−−−−−+ +−−−−−−−−−−−−−−−+
That shows how the prototype is useful for shared features. a1
and a2
don't need to have their own copies of method
, they just inherit it from their prototype.
Side note: __proto__
is deprecated. Use Object.getPrototypeOf(a)
to get the prototype of a
, rather than a.__proto__
.
Upvotes: 4
Reputation: 198304
A.prototype.constructor == A
for any function A
; a.__proto__ == A.prototype
for any object a
constructed by new A
; a.constructor
doesn't exist, so it is looked up up the prototype chain just like any other attribute, and is found at a.__proto__.constructor
.
Upvotes: 2