Difference Between Call and Apply

What is the difference between call and apply?

The difference is that apply lets you invoke the function with arguments as an array; call requires the parameters be listed explicitly. A useful mnemonic is "A for array and C for comma."

See MDN's documentation on apply and call.

Pseudo syntax:

theFunction.apply(valueForThis, arrayOfArgs)

theFunction.call(valueForThis, arg1, arg2, ...)

There is also, as of ES6, the possibility to spread the array for use with the call function, you can see the compatibilities here.

Sample code:

function theFunction(name, profession) {
console.log("My name is " + name + " and I am a " + profession +".");
}
theFunction("John", "fireman");
theFunction.apply(undefined, ["Susan", "school teacher"]);
theFunction.call(undefined, "Claude", "mathematician");
theFunction.call(undefined, ...["Matthew", "physicist"]); // used with the spread operator

Javascript call() & apply() vs bind()?

I created this comparison between function objects, function calls, call/apply and bind a while ago:

Sample Image

.bind allows you to set the this value now while allowing you to execute the function in the future, because it returns a new function object.

Why is knowing the difference between .call() and .apply() so important?

Simply put, more advanced types of Javascript will occasionally need to use either .call() or .apply(), particularly code that is trying to proxy functions and pass on arguments or control the value of this.

If you're doing those types of things, then you have to know how both .call() and .apply() work so you can use the correct method (since they don't work identically). If you're not doing those types of advanced things, then a lot of Javascript can be written without using them.

As an interview question, I think it's a reasonable test on whether you understand some of the more advanced nuances of argument passing, calling methods and this handling in Javascript. If you want to do well on those types of questions, you will need to understand both .call() and .apply(), now how to explain what they do and how and when to use them and when you would use one vs. the other.

The whole concept of this and how it is controlled or set in Javascript is often not understood well by lesser experienced Javascript programmers (heck I've even seen some experienced developers that didn't understand it well) so quizzing a candidate on things related to that is a reasonable test and .call() and .apply() are somewhat central to that.

If you were developing library or framework code, you'd be even more likely to be using .call() or .apply() in the work you do.


Here's a basic summary:

Every function in Javascript is an object that has some properties. So, in addition to be able to call a function like func(), you can also reference the properties on it like func.length.

Two of the properties that every function has are .call() and .apply(). They both allow you to call the function in somewhat different ways than just calling it as func().

.call()

We all know, of course, that if you just want to call a function with a fixed number of arguments, that you can just execute func(arg1, arg2) and those arguments will be passed to the function, but what if you want to control what the this value will be when you pass those fixed arguments? Calling func as func(arg1, arg2) will cause the this value inside that function to be set to either to the global object which is window in a browser or if running in strict mode to undefined. Every function call in Javascript such as func(arg1, arg2) resets the this pointer in this way. This is where .call() comes in. You can execute:

func.call(someThisValue, arg1, arg2)

And it will do the same thing as func(arg1, arg2) except it will cause the this pointer to be set to someThisValue.

Note: you can also use .call() with just one argument and it will just set the this pointer and not pass any arguments.

func.call(someThisValue)

.apply()

But, what if your argument list is not fixed and your arguments are in a variable length array or array-like object. You can't really use .call() because you can't type out the right .call() statement for every possible list of arguments. This is where .apply() comes in. A canonical use for .apply() is when you're just trying to pass on the arguments from some other function call. This is common when you're proxying other function calls to slightly modify their behavior, but still call the original and the original either has various forms (so you don't exactly know the arguments that were passed) or lots of different types of function calls all go through this proxy. In this case, you can use .apply(), often with the arguments object. You can see an example of this in the MDN polyfill for .bind().

Let's say I want to hook some existing function named doIt() for logging purposes and doIt() has a number of different ways that it can be called. Using .apply(), I could do it like this:

// regular function already defined in your program
function doIt(arg1, arg2) {
// do something
}

// then actual usage elsewhere in the program would be just this:
doIt("foo", "bar");

// now install a proxy that can intercept all calls to doIt() and
// add some behavior before and after
(function(origDoIt) {
// replace doIt function with my own proxy
doIt = function() {
console.log("before doIt()");
// call the original function with all the arguments and this pointer
// that were passed
var retVal = origDoIt.apply(this, arguments);
console.log("after doIt()");
return retVal;
}
})(doIt);

FYI, .apply() can also be used to just set the this pointer as in:

func.apply(someThisValue)

In that particular case (and only that case), it works identically to .call().


Here's one of my favorite uses of .apply(). The Math.max() method accepts a variable number of arguments and it will return the largest number of any of those arguments. Thus:

Math.max(1,2,3,4)

will return 4.

But, using .apply(), we can find the max number in any array.

var list = [999,888,777,666,555,444,333,1000];
var m = Math.max.apply(Math, list);
console.log(m); // 1000

We're using .apply() to send the entire list array as the arguments to Math.max() so it will operate on the entire array.

Note, when ES6 is fully implemented everywhere or in your particular execution envirionment, you can also use the new spread operator to do something similar:

var list = [999,888,777,666,555,444,333,1000];
var m = Math.max(...list);
console.log(m); // 1000

which becomes kind of a shorthand for what we were doing with .apply()

what's the difference between 'call/apply' and 'bind'

bind returns a function which will act like the original function but with this predefined. It is usually used when you want to pass a function to an event handler or other async callback.

call and apply will call a function immediately letting you specify both the value of this and any arguments the function will receive.

Your second example defines an anonymous function which calls apply. This is a common pattern; bind provides a standard implementation of that which allows you to do it with a simple function call (thus being quicker and easier to write).

Difference between .call and .apply

I think you've just discovered the difference yourself.

call is almost identical to way you would normally call a function except there is an extra parameter at the start of the parameter list where you place the reference for the this object.

apply also has the first parameter as the this object but the second parameter is expected to be an array. This array is used to supply all the arguments that the called function is expecting. Element 0 maps to the first argument in the functions argument list, element 1 to the second and so on.

what is the difference between .apply and .call

.apply need you to pass the arguments as an array.

SO

myApp.hide.call(numbers, numbers.div)

should be same as

myApp.hide.apply(numbers, [numbers.div])

But, in your myApp.hide function, there is no this, so the first parameter of .call or .apply can be anything else, it doesn't matter.

Using apply() vs call(), which one to use in this case?

Apply takes a single array of arguments, useful for method chaining, the javascript equivalent of calling super. in Java etc.

function makeNoise() {
Foo.prototype.makeNoise.apply(this, arguments);
}

Call takes list of parameters, more useful other situations where the arguments are only available as single variables.

fn.call(this, x, y, z);

which would just be shorthand for

fn.apply(this, [x, y, z])

Given you have an array of arguments you need to use apply()

What is the difference between call and apply method in jQuery

They're not jQuery things, they're JavaScript things.

They do the same thing: They call the given function using a specific value for this within the function call. The only difference is how you specify the arguments to pass to the function. With call, you specify them as a series of discrete arguments (after the first one, which is what to use as this). With apply, you specify them as an array (again after the first arg, which is what to use as this).

So say we have:

function foo(a, b, c) {
console.log("this = " + this);
console.log("a = " + a);
console.log("b = " + b);
console.log("a = " + c);
}

These two calls do exactly the same thing:

foo.call("bar", 1, 2, 3);
// Note --------^--^--^--- a series of discrete args

foo.apply("bar", [1, 2, 3]);
// Note ---------^-------^-- args as an array

In both cases, we see:


this = bar
a = 1
b = 2
c = 3


Related Topics



Leave a reply



Submit