Reputation: 7648
I've a simple example from MDN.
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
constructor(name) {
super(name); // call the super class constructor and pass in the name parameter
}
speak() {
console.log(this.name + ' barks.');
}
}
let d = new Dog('Mitzie');
d.speak(); // Mitzie barks.
Now, in subclass Dog
how does this.name
works under the hood. Since this
refers to Dog
class instance and name is not something which exists on Dog instance. So to access that we use super call which invokes parent's constructor. I get that it looks up.
But can someone please explain via the prototype mechanism (I'm comfortable in understanding the prototype lookup and chaining mechanism).
I'm sure deep down it will boil down to that but not clear about intermediate steps in between. Thanks!
Upvotes: 0
Views: 43
Reputation: 7648
Actually, what I wanted to ask was under the hood. So, here's the answer based on @Jai's pointer in comments that I was looking for.
I ran the class based code through es5compiler or any compiler and got this conversion
var Dog = /** @class */ (function (_super) {
__extends(Dog, _super);
function Dog(name) {
return _super.call(this, name) || this;
}
Dog.prototype.speak = function () {
console.log(this.name + ' barks.');
};
return Dog;
}(Animal));
So basically
return _super.call(this, name)
inside Dog function explains the confusion of this
reference inside speak
method of class Dog. It changes the context through call()
Upvotes: 0
Reputation: 371019
this refers to Dog class
No, this
refers to the instantiated object. The instantiated object has an internal prototype of Dog.prototype
, and Dog.prototype
has an internal prototype of Animal.prototype
.
Since this
refers directly to the instantiated object (in both constructors, and in all of the methods),
this.name = name;
puts the name
property directly on that object, so it's completely fine to reference d.name
, or, inside one of the methods, this.name
:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
constructor(name) {
super(name); // call the super class constructor and pass in the name parameter
}
speak() {
console.log(this.name + ' barks.');
}
}
const d = new Dog('Mitzie');
const dProto = Object.getPrototypeOf(d);
const secondProto = Object.getPrototypeOf(dProto);
console.log(dProto === Dog.prototype);
console.log(secondProto === Animal.prototype);
console.log(d.hasOwnProperty('name'));
Upvotes: 3