I'm getting stuck because of less understanding of prototypal inheritance. I want to know what is prototypal inheritance exactly and how it is implemented.
Could you please show one ease example?
Any help is appreciated.
I'm getting stuck because of less understanding of prototypal inheritance. I want to know what is prototypal inheritance exactly and how it is implemented.
Could you please show one ease example?
Any help is appreciated.
Imagine you have an object and you want to look up a property. Now imagine the property doesn't exist. What if you could make it automatically continue the search for that property on a different object? That's basically what prototypal inheritance is.
So then the only question is how to create this relationship between objects. Well, that's the weird part.
I'll start with the main, historical way of doing it. That is using functions.
First thing to note is that a function in JavaScript is itself an object. It can have its own properties, and it uses prototypal inheritance to gain access to other properties.
So let's start by creating a function.
function Foo() {
// our function
}
So now we have a function named Foo
. Our new function automatically gets a property named prototype
when it's created. That property references an (almost) empty object.
console.log(typeof Foo.prototype); // object
Why does that property and object exist? Well, they exist to support the weird way that JavaScript has formed that relationship between objects that I described above.
Basically, the Foo.prototype
object is what we're going to use as the "backup" object when looking for new properties on our objects. But we still haven't formed any special relationship between the object we want to use, and the Foo.prototype
object.
To do that, we actually invoke the function using the new
operator.
var my_object = new Foo();
And there we go. So now my_object
is a new, empty object. But it has in its "prototype chain" that object that is dangling from our Foo
function off of its .prototype
property. In other words, when we look for a property on my_object
, if the property doesn't exist, it'll continue the search on the Foo.prototype
object.
Trouble is that we haven't added anything that we might find useful to Foo.prototype
. But there actually is one property on that object. That property was also automatically created when we made our Foo
function, and it's the .constructor
property.
What does that property reference? It has a reference back to the Foo
function. In other words:
Foo.prototype.constructor === Foo; // true
Alright, so if our my_object
is empty, and if when looking for a property on my_object
that doesn't exist, it continues the search on the Foo.prototype
object, then that should mean that we should be able to automatically get to the Foo.prototype.constructor
property from my_object
.
my_object.constructor === Foo; // true
And it works. Since my_object
didn't have a property named constructor
, it continued its search on the object from which it inherits, which is Foo.prototype
, which as we know, has a .constructor
property that refers to the Foo
function.
Super. But how do we set up other properties that are more useful to us in our code? We just add them to Foo.prototype
. That will let our my_object
find those properties if the object doesn't own them directly.
// give a custom property to `Foo.prototype`
Foo.prototype.bar = "foobar";
// see if we can access that property on your object
my_object.bar === "foobar"; // true
Sure enough, it worked. So let's see if we can create a new object from Foo
that also has access to that .bar
property.
var another_object = new Foo();
another_object.bar === "foobar"; // true
Again, it works. This is because all objects created by invoking Foo
using the new
keyword will have in their prototype chain the Foo.prototype
object. In other words, Foo.prototype
is shared among all instances created from Foo
.
So if we now modify the Foo.prototype.bar
property, it will be reflected in both objects we created.
Foo.prototype.bar = "raboof";
my_object.bar === "raboof"; // true
another_object.bar === "raboof"; // true
So we can see that both of our objects are simply looking for properties that they don't have by passing the search on to the next object in their "prototype chain", which is that weird object dangling off the Foo
function... Foo.prototype
.
There are newer ways to set up this object relationship, but this is the original way, and in spite of its weirdness, should probably be understood first.
This is how I understand it:
This could be considered a constructor
var Thing = function(){
this.method1 = function(){
alert( "method 1" );
}
}
This is an instance of it
var a_thing = new Thing();
a_thing.method1();
Now, if you add something to the prototype of the constructor, it is automatically available to the already instantiated object.
Thing.prototype.method2 = function(){
alert( "method2" );
}
a_thing.method2();
Hope this helps.
This is the simplest example I can think of,
pizza class inherits from circle by using this line:
pizza.prototype = new circle();
Full example:
<html>
<head>
<script>
// base class
function circle(radius){
this.radius = radius;
this.getArea = function ()
{
return (this.radius * this.radius) * Math.PI;
};
this.foo = function ()
{
return "circle foo";
};
return true;
}
// child class
function pizza(flavour, radius){
circle.call(this, radius);
this.flavour = flavour;
this.foo = function ()
{
return "pizza foo";
};
return true;
}
// Inheritance
pizza.prototype = new circle();
function Go(){
// Instancing new object
var myCircle = new circle(8);
var myPizza = new pizza("Onion", 5);
// Calling property
var pizza_area = myPizza.getArea();
// Calling override foo function
var foo = myPizza.foo();
// Calling foo base class
var base = pizza.prototype.foo.call(myPizza);
//Line.prototype.someFunction.call(myLine);
var isBase = myCircle instanceof pizza;
isBase = myPizza instanceof pizza;
}
</script>
</head>
<body onload="Go();">
</body>
</html>