jmnf:2 Objects part 1

javascript magic-ninja-foo episode 2: Objects - part 1

In my previous jmnf post I mentioned that javascript functions are really objects that can be manipulated. In the following few posts I will go a little more detail about Javascript objects and object orientation, this first one will focus on them from a structural standpoint.

Javascript actually has a relatively small number of data types. The most important data types are numbers, booleans, and objects. In addition, there is a subset of a few 'specialized' objects that behave slightly differently from normal objects and for most purposes can be treated as separate data types. These are strings, functions, and arrays. There are a couple of other data types, but those are the most important.

So what is a javascript object? In their most fundamental form, javascript objects are associative arrays. Building on that idea, which should be familiar to Perl programmers, we can begin to understand how javascript objects work, and how to manipulate them.

Objects in javascript have a certain fluidity to them. Unlike class based languages, the structure of an object in js can change throughout its lifetime. This is a direct consequence of the object data type being essentially an associative array. There are a several ways to construct objects, but for now we'll begin with this notion of an object as associative array.

var myNewObject = {};
myNewObject["name"] = "MikePK";

We started by using an 'object literal' to create an empty object. We then created a new property of the object called "name" and associated a value with it. If I wanted to pull the name element from the object I can use the bracket operator myNewObject["name"] which will return the value. I could also use a variable containing the string to access the property. Remember that js is untyped, therefore any data type can be associated with the key value, this will be important later.

In the previous example we used an object literal to create an empty object. The syntax for an object literal consists of a series of 'label:value' pairs separated by commas and enclosed in curly braces, it looks like the following:

var myNewObject = { 
   name:"MikePK", 
   age:31, 
   height:76,
   occupation:"entrepreneur" 
};

This is a totally valid javascript object. I can also add properties to this object as I did above. Now I mentioned in my previous post that the creators of javascript seemed to have in mind making the transition to js from other programming languages easy as one of their design goals. With that I bring up the other, more common, way of accessing the properties of an object, the dot operator.

var current_name = myNewObject.name;
/*adding a new property*/
myNewObject.title = "javascript ninja wannabee";

This dot notation should be familiar to anyone coming from other object oriented languages as the means of accessing the public variables in an object. You'll notice that I can also use the dot operator to *create* new properties, just like the bracket operator case above.

In most cases the dot and bracket means of getting and/or creating object properties are equivalent. There is one important difference though, you'll notice that in the bracket case the key is a data value (literal or variable), whereas in the dot case it's part of the javascript statement.

This leads to an interesting facility in js, the ability to iterate over the properties of an object. The following example uses the 'in' operator which iteratively returns all the keys of the assoc. array.

var property;
for(property in myNewObject) {
   alert(myNewObject[property]);
   }

You can see that, with some clever programming, you could also programmatically create objects during runtime with arbitrarily generated keys and values.

Now all of this talk of objects as associative arrays leads to the inevitable question, shouldn't objects have both state *and* behavior? This is where the previous post and this post converge. Remember the following points, javascript is untyped, functions are data types, and objects can associate any key with any data type.

var HelloWorld = function() { alert("Hello World") };
var Greeter = {};
Greeter.Hello = HelloWorld;
/*wait for it... drumroll....*/
Greeter.Hello();

We've taken a function object and added it as a property inside the object. This now makes the Greeter object contain the function "HelloWorld" or in object oriented parlance, it now has a method (granted a not very interesting method).

This is just the tip of the iceberg, as this is sure to bring to mind other questions.

The next article: what is 'this'? Raise the 'scope'!