views:

118

answers:

5

I quite often have to bind? some function that requires arguments. The solution I use is wrapping the function to bind inside an anonymous function.

function foo( arg_0 ) {
   // do stuff with: arg_0
}

function bar() {
   var abc;
   // stuff happens
   abc = 'some value';
   attachEventHandler(elementId, 'click', function(){foo( abc );});
}
bar();

Is there a more elegant way of doing this?

+10  A: 

You can make a curryer, like this:

function curry(func) {
    var functionArgs = Array.prototype.slice.call(arguments, 1);
    return function() { return func.apply(this, functionArgs); };
}

Usage:

attachEventHandler(elementId, 'click', curry(foo, abc) );

Alternatively:

Function.prototype.curry = function() {
    var func = this, functionArgs = arguments;
    return function() { return func.apply(this, functionArgs); };
}

Usage:

attachEventHandler(elementId, 'click', foo.curry(abc) );
SLaks
great idea, thanks +1
Gaby
Should it be spelled currier?
SLaks
I never thought JavaScript would start making me hungry...
Kit Menke
(Just to let others know) Alternate version (Function.prototype) works even in IE6.
Jacco
A: 

you may even want to take look at some js libs

for example YUI

what you do

YUI().use('node',function(Y){
  Y.one("#elementID").on('click', function(){
    // do your stuff here
  });
});
Dapeng
This doesn't answer the question.
SLaks
+1  A: 

That's fine. What you have is essentially the use of a callback or "delegate".

SLaks' curryer is some nice syntactic sugar if you have to do this often within a script.

Peter Bailey
A: 

So in your code you have a function foo() that takes an event as the argument? If that's all you want to do then your attachEventHandler() can be written just as:

attachEventHandler(elementId, 'click', foo);

What's going on there is that instead of calling foo() it's passing a reference to foo().

Is this closer to what you're thinking?

Amy
He appears to be trying to curry parameters; I believe that the `abc` parameter in his anonymous method is only there by mistake.
SLaks
+1  A: 

You can hide the word function if you prefer 'curry', but your original method does the same thing without the overhead.

You do not need the argument in the parentheses in the anonymous function- it is still in scope when you define it-

abc = 'some value';
attachEventHandler(elementId, 'click', function( abc ){foo( abc );})
could be:
attachEventHandler(elementId, 'click', function(){foo(abc)});
kennebec
Actually, putting the argument in parentheses is not the same. His original code (before he edited the question) would pass the event object that is given to the anonymous function to `foo`.
SLaks
This question was not about passing an event, so, in this case your answer is spot on. If I was to pass an event, the first solution would be different from the second.
Jacco