196

Is it possible to pass a javascript function with arguments as an argument?

Example:

$(edit_link).click( changeViewMode( myvar ) );
Steve Chambers
39.8k29 gold badges179 silver badges222 bronze badges
asked Aug 19, 2009 at 14:13
2
  • 5
    It looks like JQuery, and most likely is, but that is irrelevant. The use or parameters and functions is the same regardless of what Javascript libraries you use. Commented Aug 19, 2009 at 14:18
  • 1
    If you are working with React, consider stackoverflow.com/questions/41369497/… Commented Feb 3, 2020 at 1:22

7 Answers 7

310

Use a "closure":

$(edit_link).click(function(){ return changeViewMode(myvar); });

This creates an anonymous temporary function wrapper that knows about the parameter and passes it to the actual callback implementation.

answered Aug 19, 2009 at 14:14
Sign up to request clarification or add additional context in comments.

6 Comments

If you're wanting to call a function on an object, you need to call bind(). myObj.click( function() { this.doSomething(); }.bind( myObj ) ); That will make "this" be myObj.
Isn't this a performance issue when dealing with a lot of these? E.g. You're rendering a onPress in a Row and you have 10,000 rows. This creates a new anonymous temporary function wrapper for each Row. Is there any other way to do it?
@JoshuaPinter The technique itself is not an issue. If you need the same function call 10,000 times, you can simply save the wrapper in a variable, so you create it only once. If you need to pass 10,000 different contexts, there is little you can do. Beware of premature optimization: As always with performance, you need to measure to see if there is a problem or not. Today's JavaScript engines are very powerful and might optimize code in surprising ways.
@FerdinandBeyer Awesome, thanks for the tip. A friend told me it was bad practice and that you should instead use this.myFunction = this.myFunction.bind(this) in your constructor method. But, like you said, when you have to pass different contexts to it for each one, like all different rows that you click on to open that row's detail page, it's not avoidable.
In ES6 you can simplify it by using arrow functions. $(edit_link).click(() => changeViewMode(myvar));
|
54

Use Function.prototype.bind(). Quoting MDN:

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

It is supported by all major browsers, including IE9+.

Your code should look like this:

$(edit_link).click(changeViewMode.bind(null, myvar));

Side note: I assume you are in global context, i.e. this variable is window; otherwise use this instead of null.

answered Jan 2, 2016 at 14:33

4 Comments

Thanks, this helped me. Used it like this: $.ajax(url).done(handler.bind(this, var1, var2));
Which option is best ? Using closure or using the bind function ? Please let me know if there is any performance impact
I've been using fn.bind(this) to resolve the dreaded this confusion in callback functions without understanding the broader purpose of bind – but now I get it! Thanks 🙏
19

No, but you can pass one without parameters, and do this:

$(edit_link).click(
 function() { changeViewMode(myvar); }
);

So you're passing an anonymous function with no parameters, that function then calls your parameterized function with the variable in the closure

answered Aug 19, 2009 at 14:15

Comments

17

Or if you are using es6 you should be able to use an arrow function

$(edit_link).click(() => changeViewMode(myvar));
answered Feb 13, 2018 at 2:12

Comments

8

Yes, like this:

$(edit_link).click(function() { changeViewMode(myvar) });
answered Aug 19, 2009 at 14:15

Comments

3

You can do this

var message = 'Hello World';
var callback = function(){
alert(this)
}.bind(message);

and then

function activate(callback){
 callback && callback();
}
activate(callback);

Or if your callback contains more flexible logic you can pass object.

Demo

answered Aug 24, 2016 at 14:17

Comments

2

This is an example following Ferdinand Beyer's approach:

function function1()
{
 function2(function () { function3("parameter value"); });
}
function function2(functionToBindOnClick)
{
 $(".myButton").click(functionToBindOnClick);
}
function function3(message) { alert(message); }

In this example the "parameter value" is passed from function1 to function3 through function2 using a function wrap.

answered Sep 7, 2016 at 14:32

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.