Another go-to interview question, as it’s quite tricky to concisely summarise if you don’t fully understand call and apply.
Simply put, the methods
apply are methods on the Function prototype. This means that they’re functions that you can call on…well, functions.
The conventional way to call a function, and one which you may be more familiar with, is:
For the most part, this way of calling functions is going to suit our needs fine. It only really gets interesting when we have the
this keyword inside our called function.
Let me illustrate:
So, we want to keep our
reverseName function fairly generic, and not have to tie it to any particular object. So how can we call it and make the
this value point to our
user object literal?
If we did this:
then we’d receive an error saying
Uncaught TypeError: Cannot read property 'split' of undefined. And that’s because the property
fullName doesn’t exist on the
Window object. Why are we suddenly involving the
Window object? Because when you call a function, the object to the left of the function name becomes the
this value inside the called function. And because we called
reverseName() without anything to the left of it, the context of
this inside the function becomes the
Window object by default.
Enter call & apply.
These are two alternative ways to call functions, very similar to bind, but slightly different, which we’re about to see. All three functions (call, apply & bind) allow you to manipulate or set the value of
this inside the function you’re acting on. However, unlike
apply will invoke the function immediately. Like so:
We can see that it worked successfully, and reversed the string “Morpheus” from the user object. The first parameter to both call and apply is the value you want
this to be inside the invoked function. So as we pass in
reverseName the value
this points at our
Now, as for the subtle difference between the two. Call and apply both, conceptually, achieve the same result. The only difference between them is how they handle parameters. The code below should show this nicely:
As you can see,
call takes separate parameters, one after the other, but
apply takes an array. Both
console.log functions inside
reverseName log out the same things: “trinity cypher”. So it’s all about how you pass the parameters in.
Hope this clears up a potentially tricky topic and you can concisely explain it to the next person who tries to catch you out.