Javascript Jems - The Prototype
Written by Ian Elliot   
Monday, 04 October 2010
Article Index
Javascript Jems - The Prototype
Prototype properties
Dynamic Javascript

The prototype idea is confusing. It seems to have something to do with the function that created an object rather than the object itself - yet it provides a way of augmenting the properties and methods an object has. Once you know the link between constructor and object instance this isn't so confusing.


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

 

The prototype idea is perhaps the one that sinks most beginners' attempts to understand Javascript's object oriented approach.

The good news is that you don't need to use it and hence you don't need to understand it.

For most Javascript programmers the prototype idea and the prototype property in particular can be ignored.

But...

there are situations in which using the prototype facility can make an object oriented design practical and there are times when it makes things neater and more robust.

Finally there is always the very real chance you will have to deal with someone else's code that uses or more likely misuses the prototype.

So while you can ignore it my advice is not to.

First a summary of Javascript objects so far:

  • Javascript doesn't use classes, you simply create objects.
  • To do this it is a good idea to use functions to build objects for you and this gives rise to the idea of the object factory and more specifically the constructor.
  • Javascript doesn't really have much use for the concept of type and instead it links the idea of type to the constructor that created the object.
  • That is you can consider the function object represented by the constructor of an instance of an object to be its "type".

Now we have to move on to consider a small problem of efficiency in object construction.

The point problem

Currently we have all of the tools we need to work with Javascript in an object oriented way.

We don't have a mechanism for inheritance as yet but it is easy to see how we can borrow properties and methods from one object to create a new one - something we will look at in more detail later.

At the moment however there isn't much call for inheritance in an environment that it essentially dynamic and object rather than class oriented.

Put simply most Javascript projects don't need to build up a hierarchy of objects to solve a problem.

The basic approach is that if you need an object create it, add the methods and properties it needs and if it needs any more add them when ever you feel like.

Now consider the following program snippet:

function Point(){
this.x = 0;
this.y = 0;
this.setPoint = function(x, y){
  this.x = x;
  this.y = y;
 }
};
var points=new Array(10);
for(var i=0;i<10;i++){
points[i] = new Point();
};

This is fine for creating an array of 10 point objects but notice that there is an inefficiency that might become an issue if the array was bigger.

The setPoint function is created anew for each and every point object. That is every point in the array has its own copy of the setPoint function and we really only need one. In general the methods that object instances share generally only differ in the data that they process.

To avoid having to have a copy of a function in every instance we can move the function to a location where all of the object instances can make use of it. For example we could do the job manually:

function SetPoint(obj,x,y)
{
 obj.x=x;
 obj.y=y;
}

and an instance would use the method as in:

SetPoint(point,1,2);

This isn't a nice way to do the job however because it is clear that SetPoint isn't part of the object it is being used with and you have to remember to include a reference to the object in the actual call.

The constructor's prototype

To make this sort of reuse possible Javascript implements the prototype mechanism - and this is perhaps the most complicated aspect of Javascript. However it is only complicated because of the connection between constructor and object instance.

Every function object has a special prototype property - and this is true whether or not it is used as a constructor. When the function isn't used as a constructor it can be ignored but when the function is a constructor it can be used as another way of defining properties and methods that belong to the object created.

The key to understanding what happens is a simple rule that Javascript implements.

If you try to use a property or a method that does not exist then Javascript will look for the method in the constructor's prototype property.

The prototype property is usually initialised to be an object and it is this object, usually referred to as the prototype object that stores the prototype properties and methods.

Notice it is the constructor's prototype property that is involved and not the object instance's.

The reason it is a property on the constructor that is used and not a property on the object is very simple. A single constructor may be used to generate hundreds or thousands of new objects. If the prototype was implemented by each object then we would do nothing for the inefficiency problem that we started to solve.

However for the hundreds or thousands of objects created by the constructor - there is only one constructor and only one prototype property. 

What this means is that the objects constructor acts as a sort of central store for all of the methods that are common to all of the instances of the object that have been created by the constructor. The prototype can also be used to store common properties but in this case, as we will discover there is no saving in storage - but there are other advantages.

Banner

<ASIN:0321683919>

<ASIN:0596806752>

 



Last Updated ( Monday, 18 October 2010 )