I assume you are wondering why you have to provide name
as parameter to Emperor
and this.name = name;
inside the constructor.
Prototype inheritance in JavaScript is very simple, there is no hidden magic going on. The only connection you provided between Emperor
and Penguin
is in this line:
Emperor.prototype = new Penguin();
Emperor.prototype
is now an instance of Penguin
, but it could be any object for that matter. The function Emperor
does not know anything about the function Penguin
, so it does not magically call Penguin
.
When you call a function (Func
) with new
, all it does is creating a new empty object, whose prototype is the functions prototype
property (Func.prototype
). This object will become the this
value inside the constructor and will be returned implicitly if no other object is returned.
But what about the name inherited from the Penguin class constructor? Where does it go?
It's a property of Emperor.prototype
and is shadowed by each Emperor
instance's name
property.
Have a look at my answer here where I created some nice ASCII charts explaining the relation between instances and their prototypes.
Note: Emperor.prototype = new Penguin();
is actually not a good way of establishing the inheritance. What happens if Penguin
requires an argument? What would pass?
At this moment you actually don't want to create a new instance of Penguin
, you only want to hook up Penguin
's prototype
into the prototype chain. You can do this easily with Object.create
:
Emperor.prototype = Object.create(Penguin.prototype);
Emperor.prototype.constructor = Emperor;
But then new Emperor
objects wouldn't have a numLegs
property anymore. That's why you have to call the Penguin
on each new Emperor
instance, just like do in other languages with super()
:
function Emperor (name){
Penguin.call(this, name);
}