Is there a way in javascript to invoke a callback with an unknown number of parameters?
For example, if this was our invoking method:
function invokeCallback(callback, params) {
return callback.invoke(params);
}
And if these were our example callback methods:
function action() {
doSomeAction();
}
function greet(msg) {
console.log(msg);
}
function nameage(name, age) {
var msg = 'My name is ' + name + ' and my age is ' + age;
console.log(msg);
}
And if we could then easily call them like so:
invokeCallback(action);
invokeCallback(greet, 'Hello!');
invokeCallback(nameage, 'Bob', 20);
Then it would be great.
Is something like this possible?
forEach() method as an example, the callback function will always receive the current item, its index, and the array itself as arguments, in that order. You can name the parameters for them anything you want, or even omit them entirely, but the method will always pass them in as arguments.
Create a Callback Function by Passing a Function as a Parameters in JavaScript. We will create a callback function by passing the function as a parameter to another function. We call the function back right after the task completes. We will make a function named sayName .
A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action.
A custom callback function can be created by using the callback keyword as the last parameter. It can then be invoked by calling the callback() function at the end of the function. The typeof operator is optionally used to check if the argument passed is actually a function.
As already mentioned in the other answers, Function.prototype.apply and Function.prototype.call are the two methods you want to look at. They differ slightly in how they operate - apply takes arguments as a single array, whilst call takes them as individual parameters.
A related concept you might wish to explore where this technique is used is currying.
With regard to your example, you should look at removing the params
argument from your function definition and eliminating the opening argument which is the callback function itself:
function invokeCallback(callback) {
var params = Array.prototype.slice.call(arguments, 1);
return callback.apply(this, params);
}
Yes, this is possible. The key function is Function#apply
, which calls a function while supplying a context and parameters. The parameters are given as an array. (In this way it differs from Function#call
, where the parameters are given explicitly.)
So let's look at your function signature:
function invokeCallback(callback, params) {
We could do this very simply:
function invokeCallback(callback, params) {
return callback.apply(null, params);
}
(The first argument is the context for the function, i.e. the value of this
within it. Since we don't want to specify anything particular, we use null
.)
However, the way you call your function is slightly different:
invokeCallback(nameage, 'Bob', 20);
Do you see the difference? Here, the parameters are given explicitly, not as an array. We therefore need to handle it slightly differently. Within a function, the arguments
object contains the arguments supplied to the function. In the above case, it would contain three: nameage
, 'Bob'
, and 20
. We want to call nameage
with the parameters 'Bob'
and 20
.
The arguments
object looks like an array, but it isn't one. We therefore have to use a slightly complex call to the Array#slice
function to get the values out:
var params = Array.prototype.slice.call(arguments, 1); // get all arguments after the first one
So our function would look like this:
function invokeCallback(callback) {
var params = Array.prototype.slice.call(arguments, 1); // get all arguments after the first one
return callback.apply(null, params);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With