I'm trying to understand the prototype based inheritance in JavaScript. I read a lot and googled for hours. Now, I need to connect all those infos and hope that you can help me.
If the following 3 statements are right:
.__proto__
..protootype
.__proto__
property of an instance object points to the prototype
object property of its constructor.Let's create the following Constructor function, which creates a Dog object:
function Dog(name, color) {
this.name = name;
this.color = color;
this.bark = function() {
return `Bark, bark! My name is ${this.name}`;
}
}
Now let's create an instance of our Dog object:
let mini = new Dog('mini', 'black');
If we now open the Console and return mini, the result is this:
As expected the instance object mini has inherited all properties and methods of it's constructor.
But none of those inherited properties and methods are inside its __proto__
property. It seems rather that they are all inherited directly to the object mini itself.
Now let's add a new method to prototype object of our constructor:
Dog.prototype.myBread = function() {
return `My bread is ${this.bread}`;
}
If we now return mini in the Console, we get this result:
Again, as expected the new method myBread is passed to our object. But this time it's showing inside the __proto__
of our object mini, which references (point to) the prototype object property inside our constructor.
Now from the above simple experiment, I assume the followings:
If a constructor has its own properties and methods, they are not part of its prototype object. Those properties and methods sit directly on the constructor object.
But if we add properties or methods to .protoype
of a constructor, they get added to its prototype object. To prove it, we cannot access Dog.myBread();
but we can access Dog.prototype.myBread();
Properties and methods, that are added to the .prototype
of our constructor land in to the prototype object of the constructor and because the __proto__
of our instance object references to that prototype object, we can access them in our instance object.
If a constructor has its own properties and methods, they are not inside its prototype object. Those properties and methods sit directly on the object and are passed automatically to all its instances. In such case the __proto__
and prototype property don't play any role and have nothing to do with the inheritance process!
Now, could you help me to see if my assumptions are right or not? I'm especially curious about the last assumption.
Each object in JavaScript has a special internal property that we can access via
.__proto__
No. Every JS object has an internal [[prototype]] link, which we can access via Object.getPrototypeOf()
. __proto__
is deprecated and not available on all objects.
All constructor functions have an anonymous object property, which we can access via
.protootype
.
Yes, all constructor functions have a .prototype
property with an object, but I'm not sure why you'd call that "anonymous".
The [[prototype]] link of an instance object points to the
prototype
object property of its constructor.
Not to the property, but to the object itself. If you would reassign Constructor.prototype = …
, the [[prototype]] link of the instance wouldn't change. The link is set up with the current value of Constructor.prototype
when you call new
, yes.
As expected the instance object mini has inherited all properties and methods of it's constructor.
No, there is no inheritance in your first example. The bark
, color
and name
properties are owned by the instance. They do not belong to the constructor, they were just created by the constructor code on the instance.
- If a constructor has its own properties and methods, they are not part of its prototype object. Those properties and methods sit directly on the constructor object.
Yes, .prototype
or .name
are such properties that sit on the constructor object itself.
(Notice that every constructor, being a function object, also has a [[prototype]] link to Function.prototype
, but that's not particularly interesting here)
- But if we add properties or methods to
.protoype
of a constructor, they get added to its prototype object. To prove it, we cannot accessDog.myBread();
but we can accessDog.prototype.myBread();
This sounds like a truism, so yes.
- Properties and methods, that are added to the
.prototype
of our constructor land in to the prototype object of the constructor and because the [[prototype]] of our instance object references that prototype object, we can access them in our instance object.
Yes, this is the inheritance.
- If a constructor has its own properties and methods, they are not inside its prototype object. Those properties and methods sit directly on the object and are passed automatically to all its instances. In such case the
__proto__
and prototype property don't play any role and have nothing to do with the inheritance process!
Yes, own properties have nothing to do with inheritance.