Background
I often use the module pattern to organize my code, so that functions and constants operate on a need-to-know basis. If CONSTANT
or someFunc
are only used by anotherFunc
, then I enclose the definition of anotherFunc
in an anonymous function, so that the former two don't pollute the global scope. This helps to avoid name clashes and can also give you assurance looking at the code later of what depends on what.
This strategy does create many closures though, and I'm wondering if it might be better for performance (and more maintainable too) to pass in those dependencies explicitly. I think this has the effect of minimizing the scope chain that the function must walk to find variables.
Just to allow feedback on the module pattern itself, I've included three versions: 1) without the module pattern, 2) with it, 3) with it and scope chain minimization.
Without module pattern
var SHARED_CONSTANT;
var SOME_CONSTANT = 5;
var INNER_CONSTANT = {};
var inner = function(y) {
return y !== {};
};
var outer = function g (x) {
doSomething();
$(...).load(inner);
};
With module pattern, but no scope chain minimization
var SHARED_CONSTANT;
var outer = (function() {
var SOME_CONSTANT = 5;
var inner = (function() {
var INNER_CONSTANT = {};
return function /* inner */ (y) {
return y !== {};
};
}());
return function /* outer */ (x) {
doSomething();
$(...).load(inner);
};
}());
With module pattern and scope chain minimization
var SHARED_CONSTANT;
var outer = (function($, SHARED_CONSTANT) {
var SOME_CONSTANT = 5;
var inner = (function(SOME_CONSTANT, SHARED_CONSTANT) {
var INNER_CONSTANT = {};
return function /* inner */ (y) {
return y !== {};
};
}(SOME_CONSTANT, SHARED_CONSTANT));
return function /* outer */ (x) {
doSomething();
$(...).load(inner);
};
}(jQuery, SHARED_CONSTANT));
Summary
Which version should have better performance (and why)? Is the difference in performance significant? (I.e. is scope chain lookup expensive?) What about memory usage? (I.e. by passing in variables, I'm essentially duplicating scope, right?)
These performance tests seem to confirm what I suggested. This is premature optimization.
The tests do not show any clear favorite. For any given browser, your three snippets are close to each other, with the fastest one changing most times that I ran it. In some of the runs, the overly optimized code is even slower.
It may be because of JIT optimizations.
Lesson to learn: Keep your code as readable as possible and worry about optimization where you know you have bottlenecks.