0

I need to define a callback, which is to be called by a external library. This callback is called with 1 parameter:

function(item) {};

In my case I need to include a second parameter which I currently solve by using the 'bind' method.

function(item) {
   var value = this.value
}.bind({'value': value});

I dont want to write this every time I need to define shuch a callback function. Instead I would like to write something like this:

function(item, value) {};

Which then would be transformed into the bind method in order to satisfy the external library.

Is that possible? Or is there some other way to do this?

Thanks

7
  • Use a named function that you reference as the callback Commented Apr 12, 2014 at 10:17
  • How is this callback called? What calls it? Commented Apr 12, 2014 at 10:17
  • @adeneo: I don't understand how that would help! Can you show an example? Commented Apr 12, 2014 at 10:21
  • @JosephtheDreamer: It is called by some plugin. I don't know how it is called though! Commented Apr 12, 2014 at 10:22
  • Does value change all the time? or is it fixed? Is it just value? Commented Apr 12, 2014 at 10:28

2 Answers 2

1

You want to use closures. Here's the basic pattern, though not quite as easy as what georg suggested. But performance-wise, not nearly as much of a hit (near minimal).

Define a function:

myValueFunction(value, fn){
  return fn;
}

Since it seems you're saying your plugin is providing item and you are providing the value, you will set myValueFunction(yourvalue, function(item){}) as the callback function for your plugin (with your actual value as the parameter). It'll "return" another function with your value enclosed that takes one argument (item).

So for example if you have a plugin:

var myValue= "x";
plugin.doSomething("Plugin Argument", myValueFunction(myValue, function(item){
  console.log(item, value);
}));

This is basically what georg's answer is doing (his is in a somewhat more versatile way), but his method will will be much slower performance-wise than if you define these functions directly, particularly if you start adding many arguments.

Sign up to request clarification or add additional context in comments.

5 Comments

Let me know if you need further clarification. This is a highly versatile pattern to use in situations like this!
Thank you for the answer. This solves my problem, in this specific example, but i favor the generic behaviour answer from @georg.
Yeah, after looking it over georg's answer is somewhat versatile!
@JakobPedersen just be sure to consider the performance hit that you'd get using that method. I updated my answer to show it in context of using a closure as a callback.
@georg's answer (which uses Oliver Steele's partial function, a type of currying) is based on closures too. I don't see the need for the complexity. It does preserve the this though, but that can be done too using call if required.
0

You can use the function.partial implementation from here:

Function.prototype.partial = function(){
    var fn = this, args = Array.prototype.slice.call(arguments);
    return function(){
      var arg = 0;
      for ( var i = 0; i < args.length && arg < arguments.length; i++ )
        if ( args[i] === undefined )
          args[i] = arguments[arg++];
      return fn.apply(this, args);
    };
  };

Define the callback like this:

callback = function(item, value) { console.log(item + value) }.partial(undefined, "myValue")

Now when you call callback('myItem'), it correctly displays "myItem myValue"

1 Comment

That version of partial may fail if one of the preinitialised arguments has the value undefined. Much better to get the original from Oliver Steele's functional.js.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.