We know that one way of Javascript supporting inherence is through prototype/__proto__.
var accord = {make: 'Honda', model: 'accord'}
var civic = {model: 'civic'}
civic.__proto__ = accord
Because civic inherits from accord, civic's make will be:
civic.make
=>'Honda'
Javascript doesn't have classes. In most OO programming world, classes contain a set of methods that can be inherited from. In Javascript methods defined with object prototype, and the prototype in question is tied to the constructor of the object.
function Dog(name){
this.name = name;
}
Dog.prototype
=> Dog { }
Create a new instance of Dog:
var goofy = new Dog('goofy')
If we have a bark method defined in Dog.prototype
Dog.prototype.bark = function(){
console.log('woof, my name is ' + this.name)
}
goofy.bark()
=> 'woof, my name is goofy'
Now let's build a prototype chain. Suppose there's another object named Mammal
function Mammal(){
}
We want Dog to inherit from Mammal, so Dog instance can access Mammal's methods instantly.
Dog.prototype = new Mammal
Mammal has a method defined:
Mammal.prototype.breed = function(){
console.log("I am a mammal")
}
Since goofy is a Dog instance and Dog inherits from Mammal, goofy should be able to access breed function, right? Let's see:
goofy.breed()
=> TypeError: undefined is not a function
Huh, it looks like goofy didn't inherit from Mammal. That's the reason that it cannot access Mammal's defined method. But why? We know goofy is a Dog object instance and Dog inherits from Mammal.
goofy.__proto__
=> Dog {}
Dog.prototype
=> Mammal {breed: function}
Before we find out the reason, let's see whether we can create another Dog instance and how it behaves.
var pooh = new Dog('pooh')
pooh.breed()
=> I am a mammal
Okay, now it got us thinking. Both goofy and pooh are Dog object instance. Dog prototype inherits from Mammal. The only difference between goofy and pooh is that goofy was defined before Dog.prototype = new Mamal
happened, but pooh was defined after.
That's exactly the reason why goofy.breed() wouldn't work. In Javascript when an instance is defined, it's attached to the object's That moment's state. That means the following:
"Given a constructor named firstConstructor
, its prototype set to be secondConstructor
and thirdConstructor
only. An object created off firstContructor
currently (named firstObject
) can automatically access secondConstructor
and thirdConstructor's
methods.
If firstConstructor
now set its prototype to fourthConstructor
, firstObject
doesn't automatically have access to fourthConstructor's
methods."