Javascript Jems - a new take on objects
Written by Ian Elliot   
Tuesday, 07 September 2010
Article Index
Javascript Jems - a new take on objects
Dot notation
Dynamic objects

Banner

Dynamic objects

Once you have an object you can add to it.

That is, you can create properties and methods dynamically. Javascript is a dynamic language.

For example, the object created earlier can be built up in a number of steps. First we can create a null object:

var myObject={};

and then we can add the property and the method:

myObject.myProperty=123;
myObject.myMethod=function(){
  return myObject.myProperty;
}

The same rules about context and scope apply.

Whenever you want to create a new property or method you simply use it and assign an appropriate value. If a property or method already exists then what you get is a redefinition of the existing property or method.

However one big difference is that the this reference cannot be used when defining properties and methods in this way. The reason is obvious - this is always defined to be a reference to the current context and in this case the context, whatever it is, isn't the myObject object.

The ability to change an object by adding methods and properties also means that Javascript has a very loose idea of type.

An object is the type that it is at the current state in its life according to what properties it has. There is no concept that an object can or cannot be used in a given way because it is "of the wrong type". The object either has or doesn't have the property or method that you are trying to use. If it does, all well and good. If it doesn't then there is an problem of some sort.

If you use an undefined property then the result is "undefined" and you will see a runtime warning "object doesn't support this property or method". That is, after:

  var i=myObject.myProperty2;

the variable i has the value undefined if myObject doesn't have the property myProperty2.

You can test to see if a property is defined:

if(! typeof myObject.Property2 === 
"undefined"){
var i=myObject.myProperty2;
}

in most cases you can't catch this with a try-catch - because the assign results in a value and no-runtime error occurs.

If a method doesn't exist then the consequences are much worse and a runtime error will occur. That is

var i=myObject.myMethod2();

causes a runtime error if myMethod2() doesn't exist and this stops the execution of any code that follows.

You can of course stop such runtime errors from happening by testing to make sure that the property exists or using a try catch.

try{var i=myObject.myMethod2(); }
    catch(err){alert("no such method")}

Object as class

At this point we have more or less reached the end of the account of the foundations that Javascript provides for objects.

However, we have a problem.

Creating objects by manually coding their properties and methods is all very well if you just want one object - but what if you want lots of them.

For example. a point object might be defined as:

var point={
x:0,
y:0
setPoint:function(x,y){this.x=x;this.y=y}
};

complete with a setPoint method. Notice the use of this.x to reference the x property and x to reference the parameter.

Following this you can use the point object:

point.setPoint(10,31);
alert(point.x);

All very good and it all works but...

Suppose you now want an array of ten point objects all storing different co-ordinates - how do you create them?

In a classical object-oriented language you would use a class to instantiate as many copies of an object as you required - this is the whole point of working with classes rather than directly with objects.

But Javascript doesn't have classes so how do you create ten distinct instances of an object?

At the moment the only way you have of doing the job is to write out the code for each one:

var Points=new Array(10);
Points[0] = {
x: 0,
y: 0,
setPoint:function(x,y){this.x=x;this.y=y}
};
Points[1]={
x: 0,
y: 0,
setPoint:function(x,y){this.x=x;this.y=y}
};
...
and so on.

Clearly this isn't good.

What is important is to notice that it fails to be a good approach on a number of counts.

The first is that we have a lot of typing to declare an array of even ten objects and this makes it error prone and difficult to modify. The second problem is that a complete copy of the setPoint method is included in each and every array element. As the method is no different in different instances of the object it could just as well be shared between them.

This is an issue of efficiency and it is the problem that the prototype property is intended to solve - but more of this in a later article.

This manual approach to object creation also doesn't solve the problem of creating N objects where N is defined at runtime - i.e. read in from user input say. The solution is to use a for loop to create N new objects as in:

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

This works.

Each time through the for loop a completely new instance of a point object is created and a reference to it is stored in the corresponding array element.

Notice that this loop cannot be shortened to:

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

for reasons that by now should be obvious - point references a single instance of the object and so all of the array elements end up referencing that one single instance.

You can demonstrate the difference between the two approaches with a simple piece of code;

Points[0].setPoint(1,2);
Points[9].setPoint(50,53);
alert(Points[0].x);

In the first case the alert displays 1 because Points[0] is a distinct object to Points[9] but in the second case the alert displays 50 because Points[0] and Points[9] reference the same object.

You can see here for the first time a general approach to using Javascript objects to do the job of classes. You have to write code that either generates or duplicates an object.

That is, in Javascript object creation is a matter of writing code that creates or duplicates the object you require.

This leads us naturally on to the topic of object factories, object constructors and object duplicators.

More of which in the next installment - Javascript Jems - Type and the constructor

 

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 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  [ ... ]



JavaScript Jems - Objects Are Anonymous Singletons

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, every object can be regard [ ... ]


Other Articles

<ASIN:059680279X>

<ASIN:1430230541>

<ASIN:0321683919>

<ASIN:0596806752>

Last Updated ( Monday, 04 October 2010 )