What is the difference between using call
and apply
to invoke a function?
var func = function() {
alert('hello!');
};
func.apply();
vs func.call();
Are there performance differences between the two aforementioned methods? When is it best to use call
over apply
and vice versa?
Fundamental difference is that
call()
accepts an argument list, whileapply()
accepts a single array of arguments.Follows an extract from Closure: The Definitive Guide by Michael Bolin. It might look a bit lengthy, but it's saturated with a lot of insight. From "Appendix B. Frequently Misunderstood JavaScript Concepts":
What
this
Refers to When a Function is CalledWhen calling a function of the form
foo.bar.baz()
, the objectfoo.bar
is referred to as the receiver. When the function is called, it is the receiver that is used as the value forthis
:If there is no explicit receiver when a function is called, then the global object becomes the receiver. As explained in "goog.global" on page 47, window is the global object when JavaScript is executed in a web browser. This leads to some surprising behavior:
Even though
obj.addValues
andf
refer to the same function, they behave differently when called because the value of the receiver is different in each call. For this reason, when calling a function that refers tothis
, it is important to ensure thatthis
will have the correct value when it is called. To be clear, ifthis
were not referenced in the function body, then the behavior off(20)
andobj.addValues(20)
would be the same.Because functions are first-class objects in JavaScript, they can have their own methods. All functions have the methods
call()
andapply()
which make it possible to redefine the receiver (i.e., the object thatthis
refers to) when calling the function. The method signatures are as follows:Note that the only difference between
call()
andapply()
is thatcall()
receives the function parameters as individual arguments, whereasapply()
receives them as a single array:The following calls are equivalent, as
f
andobj.addValues
refer to the same function:However, since neither
call()
norapply()
uses the value of its own receiver to substitute for the receiver argument when it is unspecified, the following will not work:The value of
this
can never benull
orundefined
when a function is called. Whennull
orundefined
is supplied as the receiver tocall()
orapply()
, the global object is used as the value for receiver instead. Therefore, the previous code has the same undesirable side effect of adding a property namedvalue
to the global object.It may be helpful to think of a function as having no knowledge of the variable to which it is assigned. This helps reinforce the idea that the value of this will be bound when the function is called rather than when it is defined.
End of extract.
It is useful at times for one object to borrow the function of another object, meaning that the borrowing object simply executes the lent function as if it were its own.
A small code example:
These methods are very useful for giving objects temporary functionality.
I'd like to show an example, where the 'valueForThis' argument is used:
**details: http://es5.github.io/#x15.4.4.7*
From the MDN docs on Function.prototype.apply() :
From the MDN docs on Function.prototype.call() :
From Function.apply and Function.call in JavaScript :
Code example :
See also this Fiddle.
Difference between these to methods are, how you want to pass the parameters.
“A for array and C for comma” is a handy mnemonic.