1

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.

gustavohenke
  • 40,997
  • 14
  • 121
  • 129
dhirendra
  • 19
  • 6
  • 2
    http://sporto.github.io/blog/2013/02/22/a-plain-english-guide-to-javascript-prototypes/ http://javascriptissexy.com/javascript-objects-in-detail/ – manraj82 Jun 27 '13 at 13:36
  • read [Douglas "grandmastmaster of JS" Crockford's Article](http://javascript.crockford.com/prototypal.html) or a talk from [Brendan "the father" Eich](http://www.aminutewithbrendan.com/pages/20110216) – Christoph Jun 27 '13 at 13:38
  • 1
    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. –  Jun 27 '13 at 13:40
  • 1
    This should not have votes to close as "too broad". If it's a duplicate, that's one thing, but good crisp entry-level explanations are hard to find, and this is one of the important things SO can do (if we let it). – Jason Orendorff Jun 27 '13 at 13:48
  • The OP asked - "could you please show one ease example?". I think that is what I have done. – Bungus Jun 27 '13 at 14:43

3 Answers3

1

At its core

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.


How do we do it?

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.


Putting it to work

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.


See it in action

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.


Customizing for our code

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's more to learn

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.

0

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.

Bungus
  • 592
  • 2
  • 11
-1

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>
Dor Cohen
  • 16,769
  • 23
  • 93
  • 161
  • No. This is overcomplicated and uses some bad practises. It definitely is not the simplest one. – Bergi Jun 27 '13 at 13:43
  • @Bergi can you elaborate about the bad practice? – Dor Cohen Jun 27 '13 at 13:44
  • You're creating lots of methods in the constructors which better would be on the prototype - the key feature the OP had asked for actually. And your `pizza.prototype` is a circle instance without a radius - you [should not use `new` there](http://stackoverflow.com/q/12592913/1048572). – Bergi Jun 27 '13 at 13:47