OO advanced options in JavaScript – part II

In yesterday’s post we’ve started looking at how JavaScript “emulates” OO concepts available on “pure” OO languages. I’ve ended the post asking if you could detect the nasty side effect which will happen when you set the prototype property of a new “type”. If you haven’t seen it, then try to run the following code:

alert(newStudent.constructor); //prints Person function

Oopss…As you can see, Student instances’ constructor no longer reference the Student function because setting the prototype resulted in “clearing” the default constructor value associated with each functions (the default object which referenced the correct constructor was “overwritten” when we passed a new Person object to the prototype property). Correcting it is not really that complicated, though you do have to add a new line to the previous code:

Student.prototype.constructor = Student;

Another small gotcha was that we had to “duplicate” the fields inherited from the base class. With the previous sample, things were really simple. However, things will quickly get out of hand when you have a deep hierarchy (which I really don’t recommend in JavaScript – more on this in future posts) and you have a large number of fields in the base classes. There’s a small trick you can use in these cases. Take a look at the next sample:

var Student = function(name, age) {
    //simulate base initialization
    Person.apply(this, [name]);
    this.age = age;
}

The idea is really simple: we rely on the Function’s apply method and change the context that is associated to the Person function call so that it uses the current instance. The final result is that we end “adding” the base class’ fields to the current instance. The advantage of using this technique is that we end up running all the logic present on the base class constructor.

Notice that frameworks like MS ASP.NET AJAX rely on similar tricks for creating the illusion of OO construction hierarchies (do you remember the initializeBase method?). To wrap up  this post, I’d like to add that I really don’t believe that using this sort of classical OO concepts is adequate to JavaScript’s prototypal nature.  Here’s the current code we’ve written:

var Person = function(name) {
    this.name = name;
}
Person.prototype.printName = function() {
    alert(this.name);
}
var Student = function(name, age) {
    //simulate base initialization
    Person.apply(this, [name]);
    this.age = age;
}
Student.prototype = new Person();
Student.prototype.constructor = Student;
Student.prototype.printAge = function() {
    alert(this.age);
}
var newPerson = new Person("luis");
var newStudent = new Student("john", 20);

As you can see,there’s lots of small things needed for making it work. Forgetting one is so easy and you’ll only get wrong results at runtime. Not really cool,right? Even so, I still have a couple of posts on JavaScript and classical OO concepts. Stay tuned for more.

Advertisements

~ by Luis Abreu on September 5, 2009.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: