First of all, since you're using jQuery already, why not use $.proxy()
which does the same thing?
$('#button').click($.proxy(this, 'fooBar', true));
That's equivalent to your contextualize
example, as far as I can tell. And $.proxy
has the added benefit of working with functions themselves, not just their names. That means you can use it to wrap a function from some other object in a given context. I.e.
$('#button').click($.proxy(this.fooBar, someOtherContext, true));
Meanwhile, your contextualize
can't similarly "re-contextualize" a function; it only works for functions present in the context
argument.
There's also the built-in Function.prototype.bind
which will return a function bound to a given context, like $.proxy
does above:
$('#button').click(this.fooBar.bind(this, true));
It's available in all modern browsers, but if you want more compatibility, use $.proxy
.
Second: !!!(...)
. Just use 1 negation, please. It'll coerce a value to a boolean and negate it just fine; there's absolutely no reason to negate it 2 more times. Besides, since the expression in the parentheses is boolean logic, it's already is a boolean value to begin with, so it really is straight-up negation; no coercion involved. Yes, using !!
can be a handy way of coercing a value to a boolean without negating it, but even that is almost never needed since whatever you're coercing is thruthy or falsy all on its own (if(!!something)
is equivalent to just if(something)
)
I'd also skip the "is this a function" check entirely. JS will complain all by itself, if you let it. Of course, it won't call your error
function when it complains, but I'd rather have JS complain loudly than go through a custom error function. Sure, your function checks for the function's existence right away, rather than failing when trying to call it, but you can always remove the function from the context object afterward, so the upfront check guarantees nothing.
var boundFunction = Utils.contextualize(contextObj, 'fooBar');
delete contextObj['fooBar']; // boundFunction will now fail when called
Or you might want to add the function after calling contextualize
, but you can't do that right now without error
being called.
Third: You're returning a function by invoking a function that returns a function. Much like the triple-negation above, that's an unnecessary, round-about way of doing things. This will do the same
return function() {
var args = [];
$.merge(args, otherArgs);
$.merge(args, $.makeArray(arguments));
return (context[methodName].apply(context, args));
};
otherArgs
and context
are already available as closures, so there's no reason to pass them to a function, just to create new closures there.
So, yeah, your function will work, but it's unnecessary and overly complex, while being less versatile than the alternatives you already have at hand. I wouldn't recommend using it, to be honest. Sorry.
bind
(developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…)? \$\endgroup\$