36

I was wondering whether this is legal to do. Could I have something like:

function funct(a, foo(x)) {
  ...
}

where a is an array and x is an integer argument for another function called foo?

(The idea is to have one function that uses a for loop on the array, and calls that function in the params for every element in the array. The idea is so call this on different functions so elements of two arrays are multiplied and then the sums are added together. For example A[0] * B[0] + A[1] * B[1].)

JohnK
  • 6,865
  • 8
  • 49
  • 75
Spence
  • 391
  • 1
  • 3
  • 4

7 Answers7

48

I think this is what you meant.

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

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

}
Sergei Golos
  • 4,342
  • 1
  • 18
  • 21
  • 25
    +1 This is the correct answer, but could use a litle elaboration. In JavaScript, you can pass a function as an argument to another function (or assign it to a variable, etc.) but just referring to it by its name with no parentheses, like `var func = foo` or `func(bar)` (where `foo` and `bar` are functions). If you instead invoke the function by name **with** parentheses, like `var value = foo()` or `func(bar())`, then you are executing the function and the result of the function will be assigned to the variable or passed to the function, respectively. – KP Taylor Apr 22 '11 at 03:54
  • 1
    I cleaned up the answer and added comments so it *should* be much more apparent what-is-what. If you run `console.log(a+', '+typeof foo));` it will log `z, function`. – John Apr 14 '15 at 18:56
  • Furthermore to *execute* that function `foo` call it as you would any other function but as the parameter name it is assigned: `foo();` in example so no need for `eval()`. :-) – John Apr 14 '15 at 19:14
  • @Sergei Golos - Hi I just wanted to know that how can we test these types of function, i.e., funct("z", function (x) { return x; }); – Sumit Khanduri Jun 18 '17 at 06:14
  • Ideally, if you are working with functional programming your are also keeping your functions pure. Meaning that no mutation occurs and the same input will always generate the same output. This is a strength for unit testing, you can always measure the result and be sure that nothing outside the scope of the function have been effected. In the case of a function being the input into another function, the unit test should be interested in what the function you are testing does with the function you pass in. I am assuming that this is what you are specifically asking about. Right? – Sergei Golos Jun 28 '17 at 21:10
  • The answer depends on what unit testing framework you are using. In Jasmine you would use a spy. Junit has something similar. Or you could always roll your own, but really please don't. These spies are mock versions of the expected functions that track the input arguments and allow you to control the output of your fake spy function. This should give you all the insight you need to test the way your tested function interacts with the argument function. – Sergei Golos Jun 28 '17 at 21:10
29

This is not the way to declare a function with another function as one of it's parameters. This is:

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

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

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

So, the second parameter of funct is a reference to another function (in this case foodemo). Once the function is called, it executes that other function (in this case using the first parameter as input for it).

The parameters in a function declaration are just labels. It is the function body that gives them meaning. In this example funct will fail if the second parameter wasn't provided. So checking for that could look like:

function funct(a, foo) {
  if (a && foo && typeof a === 'string' && typeof foo === 'function'){
    alert(foo(a));
  } else {
    return false;
  }
}

Due to the nature of JS, you can use a direct function call as parameter within a function call (with the right function definition):

function funct2(foo){
  alert(foo);
}

funct2(foodemo('world!')); //=> 'hello world!'
Hamy
  • 20,662
  • 15
  • 74
  • 102
KooiInc
  • 119,216
  • 31
  • 141
  • 177
9

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

function funct(a, 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:

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

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 myFunc(myArray, callback, args)
{
    //do stuff with myArray
    //...
    //execute callback when finished
    callback.apply(this, args);
}

function eat(food1, food2)
{
    alert("I like to eat " + food1 + " and " + food2 );
}

//will alert "I like to eat pickles and peanut butter"
myFunc([], eat, ["pickles", "peanut butter"]); 
dallin
  • 8,775
  • 2
  • 36
  • 41
2

I would rather suggest to create variable like below:

var deleteAction = function () { removeABC(); };

and pass it as an argument like below:

removeETC(deleteAction);

in removeETC method execute this like below:

function removeETC(delAction){ delAction(); }
Abel Pastur
  • 1,905
  • 2
  • 24
  • 31
Rajkumar
  • 21
  • 1
2

What you have mentioned is legal. Here, foo(X) will get called and its returned value will be served as a parameter to the funct() method

toro2k
  • 19,020
  • 7
  • 64
  • 71
Pradeep
  • 1,108
  • 1
  • 15
  • 31
2

And what would you like it to achieve? It seems you mixed up a function declaration with a function call.

If you want to pass another calls result to a function just write funct(some_array, foo(x)). If you want to pass another function itself, then write funct(some_array, foo). You can even pass a so-called anonymous function funct(some_array, function(x) { ... }).

julx
  • 8,694
  • 6
  • 47
  • 86
  • The idea is to have one function that uses a for loop on the array, and calls that function in the params for every element in the array. The idea is so call this on different functions so elements of two arrays are multiplied and then the sums are added together. For example A[0] * B[0] + A[1] * B[1] – Spence Apr 22 '11 at 03:46
  • 1
    @Spence Then I think you've got a good suggestion for such a use case in the answer by Sergei. He declares `funct`, which takes a function as a second argument and then uses it to operate on the first argument. The first line shows an example of a call with an anonymous function passed to `funct` as its second argument. – julx Apr 22 '11 at 03:57
0

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)
    });
Biletbak.com
  • 409
  • 5
  • 14