It's not a "closure", it's just an anonymous function.
Personally I prefer the bind
version because as you say, it's more concise. However, according to this jsperf (http://jsperf.com/anonymous-function-vs-bind), it's ten times slower, which surprises me greatly, especially since the bind
used here seems to be the native one. One hypothesis is that bind
, or rather the function it generates, needs to do work around looking at the arguments passed in and constructing an argument list to pass along to the function being called.
To maintain this
, you need a variant of bind
such as Underscore's _.partial
, or you could write one yourself:
function partial(fn) {
var slice = Array.prototype.slice,
args = slice.call(arguments, 1);
return function() {
return fn.apply(this, args.concat(slice.call(arguments, 1)));
};
}
Unfortunately, the variation using partial
({ onClick: partial(someHandler, 'clicked'); }
) is still ten times slower than the anonymous function.
The hypothesis that argument list handling is causing the slowdown is supported by another test case in the jsperf, which defines a partial1
which predefines just the first of exactly two arguments to the underlying function:
function partial1(fn, a) {
return function(b) {
return fn.call(this, a, b);
};
}
Using that one, which doesn't have to create and merge argument lists, results in a slowdown of only 25-35%, instead of 90%.
If we don't care about passing through this
, which allows us to avoid using Function#call
:
function partial2(fn, a) {
return function(b) {
return fn(a, b);
};
}
Then the slowdown is just 10%.
However, if we really want to pass through this
, then we need to write the anonymous function version as
{ onClick: function(event) { someHandler.call(this, 'clicked', event); } }
which also results in a 20-25% slowdown from the original version, presumably due to the cost of invoking Function#call
. So in that sense, asusming you do want to pass through this
, the performance of the anonymous function and our home-grown partial1
, customized for number of arguments, is roughly equivalent, which is not surprising since they're essentially doing identical work.