I gave a talk at the London JS meetup last Monday evening where I compared the performance of two popular object creation patterns in JavaScript – the slides are available at Speaker Deck. Here’s a quick rundown of what covered.
Module Pattern
I like using the module pattern for a number of reasons – not least that it provides a new function scope which can be used to hide variables and methods from the public interface of the object. The module pattern looks like this:
var Module = function(arg){ var self = { getArg: function(){ return arg1; } }; return self; };
Constructor Functions
Constructor functionas are built in to JavaScript. Calling any function with the new
keyword will cause the value of this
to be bound to the function object. This means that we can assign methods and properties to this
and access them later from the returned object.
var Constructor = function(arg){ this.arg = arg; }; Constructor.prototype.getArg = function(){ return this.arg; };
Performance Testing
I wanted to figure out which pattern is faster to instantiate and to call methods on so I set up a number of tests on JSPerf:
- Object instantiation
- Method calls on instantiated objects
- Object instantiation and method calls
- Object instantiation with inheritance
- Method calls on instantiated objects with inheritance
- Object instantiation and method calls with inheritance
Vague Conclusions
The test results seem to indicate that Constructor functions are faster at instantiating an object than the module pattern. This makes sense to me as they are built into the language.
The module patern seems faster at calling methods once the object is instantiated. Adding a level of inheritance into the mix doesn’t seem to make too much of a difference.
For me this is useful information to have in the back of my mind as I am coding. There was some interesting discussion in the Q&A after my talk about premature optimization and judging each case on its merits. We discussed
I think this kind of benchmarking is an interesting excercise and is useful to gain a better understanding of the language, but ultimately you need to be making performance decisions based on actual data from your actual code.