It seems as though I am finally understanding JavaScript inheritance and how it should be done properly. Here is my code:
function Human(eyes) {
this.eyes = eyes ? "Not blind" : "Blind";
}
Human.prototype.canSee = function () {
return this.eyes;
};
function Male(name, eyes) {
Human.call(this, eyes);
this.name = name;
}
Male.prototype = Object.create(Human.prototype);
var Sethen = new Male("Sethen", true);
console.log(Sethen.canSee()); //logs "Not blind"
From what I understand, using Object.create to create your prototype object for inheritance is much better than using the new keyword. This raises a couple questions in my head.
- In the
Male.prototype = Object.create(Human.prototype)would the prototype chain beMale.prototype --> Human.prototype --> Object.prototype --> null? - In the
Maleconstructor where I useHuman.call(this, eyes);to call a super class, I have to pass eyes again in theMaleconstructor to pass it to theHumanconstructor. This seems like a pain, is there an easier way to do this? - How come sometimes I see code like
Male.prototype = new Human();... This seems to be incorrect. What is actually happening when we do that??
-
1Have you seen this stackoverflow.com/questions/13040684/… and this stackoverflow.com/questions/4166616/… ???rafaelcastrocouto– rafaelcastrocouto2013年07月18日 18:05:55 +00:00Commented Jul 18, 2013 at 18:05
-
No I haven't. I will take a look though.Sethen– Sethen2013年07月18日 18:27:31 +00:00Commented Jul 18, 2013 at 18:27
1 Answer 1
To answer your questions:
- That's correct. When you set
Male.prototype = Object.create(Human.prototype)you set the prototype chain asMale.prototype --> Human.prototype --> Object.prototype --> null. Then when you createvar Sethen = new Malethe instance (Sethen) inherits from this prototype chain. - No, you need to manually pass the parameters to the base constructor function. If you want to could set
this.eyes = eyes ? "Not blind" : "Blind"within theMalefunction itself but that would just be code duplication. What you're doing is correct. - That was the old way of doing things (before
Object.createwas standardized). I would recommend that you don't use it. For most cases it's the same as the new method. However using this method you also get unwanted properties likeeyesonMale.prototype.
When we do Male.prototype = new Human we create a new instance of Human and assign it to Male.prototype. Hence the prototype chain is Male.prototype --> Human.prototype --> Object.prototype --> null. However we also get the property Male.prototype.eyes which we don't require. That should only belong to the instance of Male.
I would recommend you read my blog post. It's a really good primer on prototypal inheritance: Aadit M Shah | Why Prototypal Inheritance Matters
3 Comments
eyes as well, but wasn't sure.constructor property.augment. It uses Object.create but you can implement it without using Object.create as well.