I am trying to understand the JS prototype
inheritance mechanism which es6 uses. When I execute the below code in the browser(chrome for example) the ironman.villain();
function fails to read the name
property from this. I expect this
to be the MarvelHero
object, but it is actually a reference to the window
. ironman.summarize()
also fails for a similar reason. Why is this?
ironman.introduce();
and ironman.friends();
correctly reads the this.name
variable and prints it.
var heroes = [];
// Hero constructor
function Hero (name, universe) {
this.name = name;
this.universe = universe;
this.introduce = () => {
return `I am ${this.name} and I belong to the ${this.universe} universe.`;
}
heroes.push(this);
}
// MarvelHero constructor
function MarvelHero (name) {
this.universe = 'Marvel Comics';
Hero.call(this, name, this.universe);
this.friends = () => {
return `${this.name} has friends: ${heroes.filter(hero => hero instanceof MarvelHero && hero.name !== this.name).map(hero => hero.name).join(', ')}.`;
};
}
// DCHero constructor
function DCHero (name) {
this.universe = 'DC Comics';
Hero.call(this, name, this.universe);
this.friends = () => {
return `${this.name} has friends: ${heroes.filter(hero => hero instanceof DCHero && hero.name !== this.name).map(hero => hero.name).join(', ')}.`;
};
}
// Parent prototype
Hero.prototype.summarize = () => {
return `${this.name} => ${this.universe}`;
}
// Inherit from Hero's prototype
MarvelHero.prototype = Object.create(Hero.prototype);
DCHero.prototype = Object.create(Hero.prototype);
// Assign constructor prototypes to self
MarvelHero.prototype.constructor = MarvelHero;
DCHero.prototype.constructor = DCHero;
// MarvelHero prototype
MarvelHero.prototype.villain = () => {
return `${this.name} has Loki`;
}
// DCHero prototype
DCHero.prototype.villain = () => {
return `${this.name} has The Joker`;
}
let ironman = new MarvelHero('Ironman');
let captain = new MarvelHero('Captain America');
let spiderman = new MarvelHero('Spiderman');
let hulk = new MarvelHero('The Hulk');
let thor = new MarvelHero('Thor');
let doctor = new MarvelHero('Doctor Strange');
let panther = new MarvelHero('Black Panther');
let batman = new DCHero('Batman');
let superman = new DCHero('Superman');
let wonder = new DCHero('Wonder Woman');
let aquaman = new DCHero('Aquaman');
ironman.introduce();
ironman.friends();
ironman.villain();
ironman.summarize();
batman.introduce();
batman.friends();
batman.villain();
batman.summarize();
Your functions are defined on the global scope, and therefore this refer to the window object.
In order for this to refer to a parent, you need them to be part of an object
{
DChero : function(name){}
}
Or wrap your code in parentheses and use it as an iife