Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript and prototype inheritance

Tags:

javascript

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.

  1. In the Male.prototype = Object.create(Human.prototype) would the prototype chain be Male.prototype --> Human.prototype --> Object.prototype --> null?
  2. In the Male constructor where I use Human.call(this, eyes); to call a super class, I have to pass eyes again in the Male constructor to pass it to the Human constructor. This seems like a pain, is there an easier way to do this?
  3. How come sometimes I see code like Male.prototype = new Human(); ... This seems to be incorrect. What is actually happening when we do that??
like image 334
Sethen Avatar asked Oct 21 '22 05:10

Sethen


1 Answers

To answer your questions:

  1. That's correct. When you set Male.prototype = Object.create(Human.prototype) you set the prototype chain as Male.prototype --> Human.prototype --> Object.prototype --> null. Then when you create var Sethen = new Male the instance (Sethen) inherits from this prototype chain.
  2. 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 the Male function itself but that would just be code duplication. What you're doing is correct.
  3. That was the old way of doing things (before Object.create was 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 like eyes on Male.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

like image 63
Aadit M Shah Avatar answered Nov 02 '22 07:11

Aadit M Shah