Functions are first class objects, which gives them full access to properties and methods. Three key methods of the Function object are call, apply, and bind. These methods allow us to reuse functions, simplify the passing of arguments, and even lock in the value of this.
In the following post, we will cover call and apply, while a follow up will talk about bind. Often these three methods are combined in the same discussion, mainly due to each being a key method of the Function object, not necessarily because they are linked. Two of these, call and apply are similar, so let’s dive in and get to some definitions and examples.
- call – method of the Function object that invokes a function with a specified this value and individual arguments
- apply – method of the Function object that invokes a function with a specified this value and an array of arguments
call and apply
- Executes the current function immediately and returns the result of the action
- Allows you to specify the value of this
- Note: if the value of this is not defined, the global (window in the browser) object will be used
So let’s say I have an awesome function:
We can invoke this function our standard way as outlined here
We can also use call to invoke our function
or use apply
Now let’s break this down a little bit as there are a few things going on
1) Why did we pass in null?
We passed in null as the first parameter to call and apply is the thisValue. In our case, we are not referencing this (it is not used at all in our function) so we can pass in null. We will explore using the thisValue parameter in the later examples when we chain constructors below.
2) What’s going on with the second parameter?
These are the parameters to our function. In the case of awesomeFunction there is only one parameter, the
awesomeValue that we will log. As call takes individual parameters and apply takes an array, we pass the parameters in accordingly.
So what if we had a function that took multiple parameters, how might that look?
Glad you asked, let’s try that out.
Now let’s invoke the standard way
How would this look with call?
So the genereal form of each is:
Great, but ummm, why would I ever want to do this? In the example you showed, isn’t the standard way less involved, less characters to type, and doesn’t require me to pass in some weird null parameter.
Why yes, the example was a simple one to show the general form of each function, you know walk before we can run and all that. Now that we have the basic syntax, let’s go further. Newness coming right up…
Benefits of call and apply
These functions allow us to reuse (borrow) functions – “you have some cool functionality, may I use it”?
Simplifying function calls
Say I have an array of numbers and I want to find the highest number. I might make a function similar to the one below
So how might we leverage our newfound tools to simplify this code? We can do so by utilizing apply.
Ok, but what else can we do?
What about other positions and players?
I leave that as an exercises for the reader/voice in my head to code up.
Why/when would you use these functions?
- you want to reuse a previously defined function, such as for inheritance
- you want to borrow another function’s capabilities
- you want to pass in an array of parameters vs specifying each parameter individually
Phew, not so bad, right? Right! In this post we have defined call and apply, provided examples that show how to use each method, and outlined key benefits. By using call and apply we can reuse an object’s methods, simplify function calls, and borrow constructors to create “class” based design. How might you be able to utilize call and apply in your programs?