Skip to Content

JavaScript & Complex Data - Objects

In my last post, we talked about how we could use a JavaScript array to represent complex data. but there's another option. And in my eyes, it's the better choice. Custom Objects.

If you've been working with JavaScript beyond the absolute basics, you likely understand how to work with an object. You have probably seen code like

mydiv.style.backgroundColor = "#FFFFFF";

This is simply refering to the object represented by the mydiv variable, and it has a property called style, which also has a property called backgroundColor. And we're just assigning a value to that property. Wouldn't it be great if we could write code something like

myFriend.name = "Bob";
myFriend.phone = "555-1234";
myFriend.call();

Well, now you can!! For this LOW LOW price of absolutely FREE, we'll throw in more than one way to make this happen!

The first method of creating a custom object is the most commonly seen (i.e. the most academic) method. You do it simply by creating a new function.

function Friend() {
  this.name = "";
  this.phone = "";
  this.call = Friend_call;
}

This function is now a "constructor" function for a friend object class. We know this because we have assigned properties to the object via the this keyword. The 'this' keyword says that for the current instance of the function, I have this particular value. But another instance of the function can have different values. For this example, we've left the properties empty. If we'd like, we can pass parameters to the function and use them to populate the properties instead. To use the object, we would issue a command similar to this:

var myFriend = new Friend();
//OR (if we have set up parameters)
var myFriend = new Friend('Bob', '555-1234');

Right away, we can then say myFriend.name = 'Bob', and then alert(myFriend.name). The properties can be any valid data type. This means we can create an object that consists of objects, that consist of arrays, that ... well, you get the picture.

We ignored the third line of the constructor so far though. This is a bit of an odd line, and is actually not a property, but a method (i.e. something the object can do). We are assuming that there is a function declared someplace called "Friend_call()". But we did not include the brackets - this is important. If we had included the brackets, then the function would get executed, and the return value of the function would be assigned to the variable this.call. By leaving the brackets off, we are saying "this.call points to the Friend_call function". And then when we call myFriend.call(), we're really executing the Friend_call function.

There's another way to do the methods though, that helps keep the object self contained.

this.call = function () { alert(this.name) };

This is making use of JavaScript's "anonymous" function feature. I've only recently started using this, but really like this approach as it saves me from having to define formal function definitions for simple tasks. I also find it easier to read the code as well - primarily because I'm now including my method functions inside the constructor function, rather than decalring the functions outside, and having to find some elaborate naming convention to avoid conflicts with function names. So, the following two classes (object definitions) are identical:

//method 1
function Friend() {
  this.call = Friend_call;
}

function Friend_call() { alert(this.name); }

//method 2

function Friend() {
  this.call = function () { alert(this.name); }
}

But do we really need to go through all that trouble to create a custom object? No, not really.

The first alternative is most definetly NOT recommended, but it does work. This approach can very quickly lead to unstructured code, which leads to bugs, which leads to headaches, which leads to extra strength asprin:

var bob;
bob.name = "Bob";
bob.phone = "555-1234";

This works, as we are essentially creating properties on the fly. Or, you can think of the variable name as "bob.name" - not an official object with a property. I don't like this approach, but sometimes it is convenient. (by the way, this also works if you add a custom attribute to an HTML tag... again not recommended though.)

There's another short cut way to creating the same object. This method is a little better, and actually has a use:

var bob = new Object();
bob = { name:"Bob", phone:"555-1234" };

This allows you to create an object, with named properties, but in a more controlled and concise manner. Now tie this in with the alternative method to create an array, and you have some real potential:

var friends = [
{name:"Bob", phone:"555-1234"}, 
{name:"Jane", phone:"555-4321"} ];

Here we are creating an array, that contains two custom objects. Now imagine using a database query with this approach - how much code do you NOT have to write now? But wait there's more!!

We can also create a custom object, with methods in a similar manner:

var bob = {name:"Bob", 
phone:"555-12234", 
call:function () {alert(this.name); } };

Are you seeing the potentials? I sure am. But of course, our enthusiasm has to be moderated by need. Honestly, how often do you run into a need for custom objects? Never mind something as arcane as this approach? Let your task at hand determine if you should use this method or not. And if you DO use this method, be very sure to comment everything thoroughly. I do not know very many people who can work with JavaScript in this manner, and if they had to maintain this code, they would be cursing me in very short order.

How about a real life example where this could be used? Sure thing, got that right here for you. (shhh, don't tell anyone, I'm modeling this on one of my current tasks). And just for the added bonus difficulty points, I'll mix most of the methods above.

Problem: We need to list all employees, with an ID, their name, and a list of the supervisor an employee has had. For each possible supervisor, we need to know when the employee started and stopped with them.

//Class definition
function Employee(id, fullname, leaders) {
  this.id = id;
  this.name = fullname;
  this.leaders = leaders;
}

//Implementation
var emps = new Array();
emps[emps.length] = new Employee(5, "Bob Smith", [
{id:1, start:'1 May', end:'5 May'},  
{id:2, start:'6 May'} ]);
emps[emps.length] = new Employee(6, "Jane Smith", 
[{id:1, start:'2 May'}]);
emps[emps.length] = new Employee(7, "Kathy Jones", 
[{id:6, start:'1 May', end:'15 May'}]);
emps[emps.length] = new Employee(8, "Sam Davis", 
[{id:6, start:'10 May'}]);

And there's your solution.

We define the Employee class and just pass the parameters to the properties. However, when we create a new Employee the leaders parameter is an array, that contains one or more custom objects, that may or may not have an end date. Phew... that's a mouthful.

Think on this for a while, and I'm sure you'll start to see fancy new ways you can use JavaScript in your pages. There's more to objects yet, like private variables and methods, and using closures for event handling. But we'll talk about this another time.

In the meantime, I really hope you enjoy your new fangled objects.
(small print - no refunds allowed).