Pass a JavaScript function as parameter

2018-12-31 16:27发布

问题:

How do I pass a function as a parameter without the function executing in the \"parent\" function or using eval()? (Since I\'ve read that it\'s insecure.)

I have this:

addContact(entityId, refreshContactList());

It works, but the problem is that refreshContactList fires when the function is called, rather than when it\'s used in the function.

I could get around it using eval(), but it\'s not the best practice, according to what I\'ve read. How can I pass a function as a parameter in JavaScript?

回答1:

You just need to remove the parenthesis:

addContact(entityId, refreshContactList);

This then passes the function without executing it first.

Here is an example:

function addContact(id, refreshCallback) {
    refreshCallback();
    // You can also pass arguments if you need to
    // refreshCallback(id);
}

function refreshContactList() {
    alert(\'Hello World\');
}

addContact(1, refreshContactList);


回答2:

If you want to pass a function, just reference it by name without the parentheses:

function foo(x) {
    alert(x);
}
function bar(func) {
    func(\"Hello World!\");
}

//alerts \"Hello World!\"
bar(foo);

But sometimes you might want to pass a function with arguments included, but not have it called until the callback is invoked. To do this, when calling it, just wrap it in an anonymous function, like this:

function foo(x) {
   alert(x);
}
function bar(func) {
   func();
}

//alerts \"Hello World!\" (from within bar AFTER being passed)
bar(function(){ foo(\"Hello World!\") });

If you prefer, you could also use the apply function and have a third parameter that is an array of the arguments, like such:

function eat(food1, food2)
{
    alert(\"I like to eat \" + food1 + \" and \" + food2 );
}
function myFunc(callback, args)
{
    //do stuff
    //...
    //execute callback when finished
    callback.apply(this, args);
}

//alerts \"I like to eat pickles and peanut butter\"
myFunc(eat, [\"pickles\", \"peanut butter\"]); 


回答3:

Example 1:

funct(\"z\", function (x) { return x; });

function funct(a, foo){
    foo(a) // this will return a
}

Example 2:

function foodemo(value){
    return \'hello \'+value;
}

function funct(a, foo){
    alert(foo(a));
}

//call funct    
funct(\'world!\',foodemo); //=> \'hello world!\'

look at this



回答4:

To pass the function as parameter, simply remove the brackets!

function ToBeCalled(){
  alert(\"I was called\");
}

function iNeedParameter( paramFunc) {
   //it is a good idea to check if the parameter is actually not null
   //and that it is a function
   if (paramFunc && (typeof paramFunc == \"function\")) {
      paramFunc();   
   }
}

//this calls iNeedParameter and sends the other function to it
iNeedParameter(ToBeCalled); 

The idea behind this is that a function is quite similar to a variable. Instead of writing

function ToBeCalled() { /* something */ }

you might as well write

var ToBeCalledVariable = function () { /* something */ }

There are minor differences between the two, but anyway - both of them are valid ways to define a function. Now, if you define a function and explicitly assign it to a variable, it seems quite logical, that you can pass it as parameter to another function, and you don\'t need brackets:

anotherFunction(ToBeCalledVariable);


回答5:

There is a phrase amongst JavaScript programmers: \"Eval is Evil\" so try to avoid it at all costs!

In addition to Steve Fenton\'s answer, you can also pass functions directly.

function addContact(entity, refreshFn) {
    refreshFn();
}

function callAddContact() {
    addContact(\"entity\", function() { DoThis(); });
}


回答6:

You can also use eval() to do the same thing.

//A function to call
function needToBeCalled(p1, p2)
{
    alert(p1+\"=\"+p2);
}

//A function where needToBeCalled passed as an argument with necessary params
//Here params is comma separated string
function callAnotherFunction(aFunction, params)
{
    eval(aFunction + \"(\"+params+\")\");
}

//A function Call
callAnotherFunction(\"needToBeCalled\", \"10,20\");

That\'s it. I was also looking for this solution and tried solutions provided in other answers but finally got it work from above example.



回答7:

I suggest to put the parameters in an array, and then split them up using the .apply() function. So now we can easily pass a function with lots of parameters and execute it in a simple way.

function addContact(parameters, refreshCallback) {
    refreshCallback.apply(this, parameters);
}

function refreshContactList(int, int, string) {
    alert(int + int);
    console.log(string);
}

addContact([1,2,\"str\"], refreshContactList); //parameters should be putted in an array


回答8:

I chopped all my hair off with that issue. I couldn\'t make the examples above working, so I ended like :

function foo(blabla){
    var func = new Function(blabla);
    func();
}
// to call it, I just pass the js function I wanted as a string in the new one...
foo(\"alert(\'test\')\");

And that\'s working like a charm ... for what I needed at least. Hope it might help some.



回答9:

Here it\'s another approach :

function a(first,second)    
{        
return (second)(first);           
}     

a(\'Hello\',function(e){alert(e+ \' world!\');}); //=> Hello world     


回答10:

In fact, seems like a bit complicated, is not.

get method as a parameter:

 function JS_method(_callBack) { 

           _callBack(\"called\");  

        }

You can give as a parameter method:

    JS_method(function (d) {
           //Finally this will work.
           alert(d)
    });


回答11:

The other answers do an excellent job describing what\'s going on, but one important \"gotcha\" is to make sure that whatever you pass through is indeed a reference to a function.

For instance, if you pass through a string instead of a function you\'ll get an error:

function function1(my_function_parameter){
    my_function_parameter();   
}

function function2(){
 alert(\'Hello world\');   
}

function1(function2); //This will work

function1(\"function2\"); //This breaks!

See JsFiddle



回答12:

Some time when you need to deal with event handler so need to pass event too as an argument , most of the modern library like react, angular might need this.

I need to override OnSubmit function(function from third party library) with some custom validation on reactjs and I passed the function and event both like below

ORIGINALLY

    <button className=\"img-submit\" type=\"button\"  onClick=
 {onSubmit}>Upload Image</button>

MADE A NEW FUNCTION upload and called passed onSubmit and event as arguments

<button className=\"img-submit\" type=\"button\"  onClick={this.upload.bind(this,event,onSubmit)}>Upload Image</button>

upload(event,fn){
  //custom codes are done here
  fn(event);
}


回答13:

You can use a JSON as well to store and send JS functions.

Check the following:

var myJSON = 
{
    \"myFunc1\" : function (){
        alert(\"a\");
    }, 
    \"myFunc2\" : function (functionParameter){
        functionParameter();
    }
}



function main(){
    myJSON.myFunc2(myJSON.myFunc1);
}

This will print \'a\'.

The following has the same effect with the above:

var myFunc1 = function (){
    alert(\'a\');
}

var myFunc2 = function (functionParameter){
    functionParameter();
}

function main(){
    myFunc2(myFunc1);
}

Which is also has the same effect with the following:

function myFunc1(){
    alert(\'a\');
}


function myFunc2 (functionParameter){
    functionParameter();
}

function main(){
    myFunc2(myFunc1);
}

And a object paradigm using Class as object prototype:

function Class(){
    this.myFunc1 =  function(msg){
        alert(msg);
    }

    this.myFunc2 = function(callBackParameter){
        callBackParameter(\'message\');
    }
}


function main(){    
    var myClass = new Class();  
    myClass.myFunc2(myClass.myFunc1);
}