Javascript Jems - Object factories, constructors and clones
Written by Ian Elliot   
Wednesday, 15 September 2010
Article Index
Javascript Jems - Object factories, constructors and clones
Parameters and constructors
Cloning

Banner

Built-in constructors

As well as custom constructors Javascript also supplies a range of constructors to create standard object.

First it is worth pointing out that not all built-in objects make use of a constructor. For example the Math object is just an object and you get on and use its methods. There is never any reason to need another Math object so it doesn't need and doesn't have a constructor.

Other objects need to be customised and so they do need a constructor. For example instances of the Array object need to be customised according to number of elements they have and so there is an Array constructor accepting a single parameter specifying the size:

var MyArray=new Array(10);

Another type of object constructor is the wrapper constructor. This takes a primitive data type and converts it into an object. For example the String constructor will wrap  a string literal in an object that has the standard string functions as methods:

var MyString=new String("Hello String Object");

Of course you normally don't have to worry about wrapping a string literal to use string methods because Javascript will do it for you automatically. That is:

MyString.length;

or

"Hello String Object".length;

amount to the same thing.

Now we come to the most misunderstood of all the built in constructors - Object. This is often explained as an alternative way of creating an object literal - it sort of is and it sort of isn't  It really creates a general object wrapper around any value you supply to the constructor. If you don't supply a value, or supply a null or undefined value, then the constructor returns an empty object:

That is:

var MyObject=new Object();

or

var MyObject=new Object(null);

sets MyObject to {}. However the effect isn't quite the same as:

MyObject={};

as will become clear in the next article - constructors do something extra things to objects.

If you supply a value to the Object constructor then it returns an object of the appropriate type.

For example:

var MyObject=new Object("Hello String Object");

sets MyObject to be a new String object.

Problems with new

There is a lot of argument about whether or not new is a good thing or if it is a bug waiting to happen.

The problem is if you write a function to create an object how is the user to know if it is an object factory or a constructor?

If you write a constructor and they forget to use new then it just doesn't work. But if you write an object factory and they put new in front of it - no harm done.

If you only plan to create limited numbers of objects then an object factory is just as good as a constructor. But when you need lots of copies then a constructor has advantages.

However this argument is largely irrelevant because it is very easy to make your constructors safe from being used without new. Simply test to make sure that this has the correct context and if it hasn't call the constructor again this time with new.

For example to protect out Point constructor from being called without new you can simply recode it as:

function Point(){
if(!(this instanceof Point))
                    return new Point();
this.x = 0;
this.y = 0;
this.setPoint = function(x, y){
  this.x = x;
  this.y = y
};
};

The first instruction checks that this is an instanceof Point and restarts the function with new if it isn't. The idea that this is set to an instanceof something which is a function is an interesting idea and again a topic for the next article.

Cloning

Finally we have the problem of making an exact duplicate of an object i.e. another instance with identical properties, methods and values.

The simple minded way of doing this is called a shallow clone:

function clone(o)
{
var c={};
for(p in o)
{
  c[p]=o[p];
}
return c;
}

The function accepts an object, creates a new object and then uses a for loop to iterate though all of the properties in the original object.

The problem with this is that if the object has properties that are themselves objects then you need to make new object clones of these. Clearly this is a case for recursion.

A deep clone function is simply:

function clone(o)
{
var c={};
for (p in o)
{
  if (typeof (o[p]== "object"))
  {
   c[p]=new clone(o[p]);
  }
  else
  {
   c[p]=o[p];
  }
}
return c;
}

This will completely clone an object.


Now we have object factories, constructors and the ability to make clones.

What else is there to look at?

Javascript type is the next big topic in our series of articles on what a Jem Javascript is.

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.

 

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:0470684143>

<ASIN:0137054890>

<ASIN:1449381871>

<ASIN:0596806752>

Last Updated ( Monday, 04 October 2010 )