jmnf 4: Objects part 2

javascript magic-ninja-foo episode 4: Objects part 2 What the heck is 'this'.

Functions with state are interesting (see previous article) but what I'm sure most people are more interested in is how that concept applies to object oriented programming in javascript (I'm sure the astute reader already has some ideas). We will return to that topic at a later point, for now we're going to talk a little more about javascript objects and how to create more complex objects. I'm going to briefly describe the 'this' keyword in javascript, as it has a very important role.

The 'this' keyword, while within the body of a method, always points to the object on which the method was called. This simple statement has some important implications.

Consider the following code.

/* define a function that uses 'this'*/
function showMyName() {
   alert(this.name+" is my name!");
}
/* manually create three object literals*/
var object1 = { name:"Bill G." };
var object2 = { name:"Steve J." };
var object3 = { name:"Larry E." };
/*assign the function as a property
   making it a method of each object*/
object1.show = showMyName;
object2.show = showMyName;
object3.show = showMyName;
/* call the method on each object*/
object1.show();
object2.show();
object3.show();

Running this code fires three browser alerts with the 'name' property of each object being displayed. What would happen if you ran the function in the global space? 'This' would then point to the global object where it's unlikely there is a name property. Therefore, the function would likely return ''undefined' is my name!'. Using the 'this' keyword and these techniques you begin to create objects that have public instance variables, and public methods that can operate on those public instance variables. This is interesting, but that seems like a lot of typing to create simple objects.

Enter the idea of a constructor. (Aha finally we're getting somewhere!) Not so fast, like most of these articles, I'm approaching the concepts obliquely to try and highlight how javascript works internally, and then showing how the designers of javascript put in syntactic sugar to make it easier for transition from other OO languages.

The basic idea of a constructor is a function that initializes an object. In javascript, unlike other more popular OO languages, the constructor not only initializes property values, it creates them as well. There is no formal notion of a 'class' from which to derive the definition of an object, so we depend on constructor functions to define the specific structure of objects (serving the role that classes do in other languages). While you would likely never see javascript code that looks like the following (for one important reason), the logical steps are what I'm trying to highlight.

The two points to remember in the following code are that objects are fluid in javascript with properties able to be added after creation and that 'this', while inside a method, points to the object on which the method was called.

function oBuild(name,age,description) {
   /*define the function that does the initializing.
      none of these properties should exist on the 
      new object so they are created and initialized*/
   function myConstructor(n, a, d) {
      this.name = n;
      this.age = a;
      this.description = d;
   }
   /*create an object with a single property
     pointing to the constructor*/
   var object = {build:myConstructor};
   /*call the constructor as a method
     on the new object*/
   object.build(name,age,description);
   /*return the newly initialized object*/
   return object;
}
var object1 = oBuild("mike",31,"entrepreneurial philosopher");
var object2 = oBuild("BillG","like 40+","uberbillionaire");
var object3 = oBuild("Steve J",12,"teh steve");
alert(object1.name);
alert(object3.description);
alert(object2.name);

Again this is long and drawn out, but the steps are what's important. Create a blank object, use a constructor function to assign structure and initial values to the object, return the newly initialized object.

Enter the 'new' operator. The new operator is essentially a shortcut that does something similar to the steps above. There is another important thing that 'new' does that will be discussed in later articles (primarily dealing with inheritance) and the reason why you generally wouldn't see code like the above example.

To use the 'new' operator, you first define a function you intend to be a constructor (any function could technically be a constructor). You then use the 'new' unary operator on the function (with any relevant arguments). The results of this operator is a new object initialized with the constructor function. This should begin to look very familiar to other OO languages.

function Orange(size,ripeness) {
   this.color = "orange";
   this.type = "citrus";
   this.size = size;
   this.ripeness = ripeness;
}
var myOrange = new Orange("huge","very green");

In this example, myOrange is a new object that derives both its structure, and initial values from the constructor function 'Orange'.

Again the design goal of the creators of javascript in making it easy to get started with javascript can lead to confusion. The results of the 'new' operator are very similar to other OO languages (a newly defined object) and the syntax looks very similar, but the way in which javascript goes about creating the object is very different. Understanding this fundamental difference, again, helps in more advanced javascript programming techniques.

Next Episode