vegUI.org home of the javascript based window manager and AJAX framework

Why you should use prototype to define object methods.

written by vegu on 21 Feb, 2007 03:29:58
I wont go over the basics of object oriented programming in javascript, and this article assumes that you know your way around with js oop at least a little bit, but.. for completeness sake

When defining an object in javascript you start with the constructor function. A function is used to construct an object as soon as it is called with the "new" keyword. You can then define methods and properties of the object by using the this keyword.

Now, when creating the methods of the object there are several common ways people go about it, the first and most common way that iv'e seen is directly defining the methods in the constructor function.

It is also the way i've been doing it for the past year or so.


Example:

code: js
function test() {

/* method */

this.dosomething = function() {
alert('something');
};

}

obj = new test();
test.dosomething();

This has the benefit of easily readable code, as the method is defined where it belongs, inside the constructor function of the object and its very compact.

However this way has a little or fairly big - depending on your application - drawback. What does a constructor function do ? Going by it's name it constructs the object. It gets called everytime you define an object using the new keyword.

code: js
/* the function test() is called and everything in that function is processed
* in order to create a new instance of the object "test"
*/


obj = new test();

Okay now take a look at our test() function. It defines a new function and assigns it to the dosomething property of our not-yet-created object. The definition part of the method dosomething happens everytime the test() function is called, and hence everytime we create a new instance of test.

Now this is generally not an issue if - as in our example - the object consists of one method, but that is hardly ever the case. Depending on your application you will end up with 20, 30 or 40 methods on some objects.
Lets assume our constructor function test() has 20 methods instead of our one measly dosomething() method. Everytime it is called it has to create those 20 methods for the new object instance to use. This is a hit on performance, and in most cases it probably wont matter since you wont notice it unless your script creates a ton of objects.

Let's test it, copy and paste the dosomething definition a couple times and rename it slightly to simulate that our test object has multiple methods.

code: js
function test() {

/* property */
this.a = 'Hello world';

/* method */

this.dosomething = function() {
alert(this.a);
};

this.dosomething2 = function() {
alert(this.a);
};

this.dosomething3 = function() {
alert(this.a);
};

this.dosomething4 = function() {
alert(this.a);
};

/* .. and so forth .. */

}

code: js
var i, o, t1 = new Date().getTime();
for(i = 0; i < 10000; i++)
o = new test();
alert((new Date().getTime() - t1)+' ms passed');

Depending on the computer youre testing on and the amount of methods you created this should be somewhere between 200ms and 1s. Okay, so who in the world creates 10000 instances of an object? Who knows :), im looking at animation ;D. However keep in mind that its not only dependent on the amount of object-instances created but also depends on the complexity and size of the object. If your object has 50 methods that are more than one liners you wont need to create 10000 of them to witness a performance hit.

So how do you prevent it?



Even if its not an issue, there is no reason to even take a 20ms performance hit if you can prevent it reasonably, any speed gain is worth looking at.

And the js prototype system offers a reasonable way for us to fix this :)

Prototype lets you add properties to any object, and then all instance of that object have access to hose properties. The properties do not get re-created everytime a new instance of the object is built. Take a look at this:

code: js
/* the constructor function for our test object */

function test() {
}

/* defining methods for our test object by accessing
the prototype of the function
*/


test.prototype.a = 'hello world';
test.prototype.dosomething = function() { alert(this.a); };
test.prototype.dosomething1 = function() { alert(this.a); };
test.prototype.dosomething2 = function() { alert(this.a); };
test.prototype.dosomething3 = function() { alert(this.a); };
test.prototype.dosomething4 = function() { alert(this.a); };

/* ... and so forth .. */

And now we check the performance:

code: js
var i, o, t1 = new Date().getTime();
for(i = 0; i < 10000; i++)
o = new test();
alert((new Date().getTime() - t1)+' ms passed');

Depending on the amount of the methods you used performance should have increased by a fairly big amount.

The good thing about prototype is that, even though the methods are defined outside of the object's constructor function you can still tell what object they belong to. Using prototype doesnt restrict to methods btw, anything that is not variable (ie, dependend on arguments passed to the constrcutor function or globals) can be defined using prototype.

Related Posts

  • No related posts



Your Comment

name:*
email-address:

Are you human?



Comments

No comments yet.