Grauw’s blog

Update: I made a new post describing updated practices that supersedes this one. I corrected the worst mistakes in this post though :).

Hey,

I was looking into OO programming in JavaScript today, and as there seemed to be various notations and I wasn’t able to quickly find a decent explanation, I decided to write a small explanation on how to do this myself. In this explanation, I will explore various aspects of creating a class called Test.

These apply to all modern browsers, including IE6, Mozilla and Opera.

First of all, before you can do anything with it, the class Test needs to exist. You can do this by declaring a constructor function:

Test = function() {
    alert('constructor function');
};

Static functions and variables

First, let’s take a look at creating static functions and variables:

Test.bla = 'static variable';

Test.alert = function() {
    alert('static function');
};

These are (of course) available without instantiating the object first.

From inside an object, other variables and functions of the object always have to be accessed by prefixing them with ‘this.’. Without that, functions on the global object (window) will be called:

Test.doAlert = function() {
    this.alert();
    alert('global alert function');
};

Non-static functions and variables

Non-static functions and variables can be created like this:

Test.prototype.bla = 'variable';

Test.prototype.alert = function() {
    alert('function');
};

And this is how you create a constructor:

Test = function() {
    alert('constructor');
};

I suppose that syntax is somewhat unexpected, without the ‘prototype’. Also, even though there’s no ‘prototype’, setting variables in the constructor (e.g. ‘this.bla = "qqq"’) will actually set it on the instance object, and not on the global (static) one. Finally, if you have a constructor on the Test object, it will overwrite the Test = {} assignment that we mentioned earlier, so you can leave that one out.

You can instantiate a Test object like this:

var bla = new Test();

Extending / inheriting

It is also possible to extend / inherit a classes in JavaScript:

NewTest = function(param) {
    Test.call(this, param);
};
NewTest.prototype = new Test();
NewTest.prototype.constructor = NewTest;

In the code above, you can see how the new constructor function also calls the original constructor. You can override any function and call its super function like this:

NewTest.prototype.alert = function() {
    return NewTest.prototype.alert.call(this)
};

However, this isn’t a 100% correct approach. For more information on why this is the case, see Correct OOP for Javascript, which is a followup on this article OOP in JS, Part 2 : Inheritance.

Well, I hope that was a useful summary :).

Grauw

Comments

Not necessary “global function” when “this” is not used by minghong at 2006-03-03 02:57

Consider the following:

Test.foo = function()
{
  function bar()
  {
    return “I’m inner function”;
  }
  window.alert( bar() ); // alert is not a global object, it belongs to window
}

So all you can say is that when “this” is not used, the function doesn’t belong to this object. It can be global (like eval), or belong to another object (like window.alert), etc.

by Grauw at 2006-03-03 12:37

Yes, right. With ‘global’ I meant the window object. I’ve changed the text a little to reflect this.

To be even more complete, the object that is used when this. is not added can actually be changed using the with statement:

Test.doAlert = function() { with(this) { this.alert(); alert('global function?'); } }

Inheritance is possible after all by Grauw at 2006-03-04 18:52

Ha, it seems that it’s possible to inherit JS objects after all. I’ve updated that last part.