Javascript Jems - Prototype Inheritance
Written by Ian Elliot   
Monday, 18 October 2010
Article Index
Javascript Jems - Prototype Inheritance
Dynamic inheritance
Prototype chains

Prototype chains

This story has been long, hard and detailed and its why its difficult for beginners to get it right. Now we have one last but fairly obvious extension.

When you specify an object as being the prototype object that object can too take part in the prototype mechanism.

That is you can write a constructor for object A.

You can then write a constructor for object B which has its prototype property set to an instance of object A.

You can then write a constructor for object C which has its prototype property set to an instance of object B

and so on.

Now if you try to access a property or method on object C Javascript first looks to see if it is defined within object C. If it isn't it then looks at the prototype to look to see if it is defined in the instance of object B. If it isn't then it looks at object B's prototype i.e. object A to see if it is defined there.

You can see that you can build up a prototype chain to implement multiple steps of inheritance. Object C inherits from object B which inherits from object A. Javascript automatically searches the prototype chain to find any undefined properties or methods and uses the first example it finds.

For example, suppose we define Point1D as:

function Point1D()
{
this.x=0;
}

and Point2D as:

function Point2D()
{
this.y=0;
}
Point2D.prototype=new Point1D();

and finally Point3D as:

function Point3D()
{
this.z=0;
}
Point3D.prototype=new Point2D();

Now if we create an instance of Point3D:

var point=new Point3D();

then the new object has a single property of its own - that is z but if you reference a y property the property chain is used and it is found in Point2D. If you reference a property x then this isn't found in Point2D but in Point1D.

That is a Point3D object inherits x and y from Point1D and Point 2D respectively.

As Point3D inherits from Point2D and Point1D Javascript also searches the prototype chain when testing type using instanceof.

That is:

point instanceof Point3D

is true and so are:

point instanceof Point2D

and

point instanceof Point1D

This is Javascript's equivalent of a type hierarchy.

Summary

It has been a long story but now you are in a position to see everything from a great height.

  • In Javascript objects are created as object litterals which can be  modified by dynamic addition or removal of properties
  • To make object creation easier we use functions as object factories to return objects.
  • To make object factories more useful and flexible Javascript provides the new operator and encourages the use of constuctors.
  • The new operator has four side effects:
  1. it automatically creates an annoymous object literal and sets the special varible this to reference it.
  2. It also returns this as the result of the function.
  3. It sets the constructor property of the object to a refernce to the function object i.e. the constructor
  4. It sets the internal __proto__ property of the object to the constructors prototype property.
  • When a property isn't found defined within an object Javascript looks in the objects prototype object for it. If it isn't found there it looks in the prototype object's prototype object and so on along the prototype chain
  • Changes to the properties of the prototype object effect the lookup for missing properties.
  • Once set the __proto__ property cannot be changed and hence the prototype of an object cannot be chanaged.
  • If an object assignes a value to a property that would otherwise be supplied by the prototype chain a local  property is created and the prototype chain isn't used.
  • The constructor used to create an object can be regarded as a definition of its "type".
  • The instanceof operator searches the prototype chain using __proto__ to see if a specifed constructor was used to create an object. This implements a sort of type hierarchy for Javascript.

The most important thing to realise is that Javascript can be used in a very simple object oriented way that doesn't use inheritance at all. Dynamic objects can be created, modified and used without any need of the old class oriented ideas of inheritance and type.

The only time when there is a strong compulsion to use the prototype mechanims is when there are lots of objects involved and you need to implement methods more efficiently. That is methods provided by the constructor aren't shared between instances but methods provided by the prototype chain are shared - hence reducing the size of the code.

Javascript has a very good approach to objects and one that suits a dynamic language.

However being such a dynamic language there are more ways of doing the same job than you might expect.  Put simply there are other ways of making Javascript objects make use of properties and methods implemented by other objects, i.e. other forms of inheritance. To find out more look out for the next article.

If you would like to be informed about new articles on I Programmer you can either follow us on Twitter, on Facebook , on Digg or you can subscribe to our weekly newsletter.

 


Javascript Jems on Objects

A complete introduction to Javascript and objects. This article is part of a series that explains how Javascript has a very special approach to objects. You might like to read them in order.

1.   A new take on objects

2.  Object factories, constructors and clones

3. Type and the constructor

4. Javascript Jems - The Prototype
5. Javascript Jems - Prototype Inheritance

 

Banner


JavaScript Canvas - Fetch API

Working with lower-level data is very much part of graphics. This extract from Ian Elliot's book on JavaScript Graphics looks at how to use typed arrays to access graphic data.



JavaScript Jems - The Inheritance Tax

JavaScript should not be judged as if it was a poor version of the other popular languages - it isn't a Java or a C++ clone. It does things its own way.  In particular, it doesn't do inheritance  [ ... ]


Other Articles

<ASIN:0321683919>

<ASIN:0596806752>

Last Updated ( Monday, 18 October 2010 )