3221

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?

iridescent
  • 303
  • 1
  • 13
John Duff
  • 35,662
  • 4
  • 31
  • 44
  • 739
    Think of `a` in apply for array of args and `c` in call for columns of args. – Larry Battle Jun 12 '12 at 06:17
  • 185
    @LarryBattle I do almost the same, but I think a in apply for array and c in call for comma (i.e comma separated arguments). – Samih Dec 06 '13 at 16:20
  • 7
    I agree it's stupid. What's annoying is that somehow this question gets asked during interviews because some influential chump added the question to their list of important js questions. – Ringo Mar 10 '14 at 22:55
  • the default "arguments" array that gets passed into a function's scope gets passed on with apply. arguments goes with array goes with apply, call accepts a manual list of models, not a collection object (array) – neaumusic Nov 26 '14 at 10:53
  • 9
    You *apply* for a job once (one argument), you [phone] *call* people many times (several arguments). Alternative: there are [too?] many *Call* of Duty games. – Gras Double Dec 04 '14 at 03:27
  • More classic, there's only one array, you *apply* it [as a whole], there're several arguments, you *call* them [in a row]. Take your pick :) – Gras Double Dec 04 '14 at 03:33
  • 1
    When the intention is to invoke a variadic function with a list of argument values regardless of "this" value, then use the ES6 spread operator, e.g. `fn(...input)` where input is an array. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator – Gajus Dec 18 '14 at 01:22
  • If you use "apply" or "call" only to chenge the "this" reference, and the function you refer to will not take any arguments, there is no diference what so ever. – DevWL Mar 23 '16 at 17:51
  • In ES6, if you've got an array of arguments `args`, only difference would be of three dots `...`. **ie:** `fn.apply(context, args)` or `fn.call(context, ...args)` – Ankit Singh Dec 14 '16 at 07:57

25 Answers25

3765

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
Zsolt Meszaros
  • 8,506
  • 12
  • 20
  • 30
flatline
  • 39,633
  • 4
  • 28
  • 37
  • Are they both supported by the majority of browsers? I seem to remember reading that `call()` was more of an IE thing. – devios1 Jun 23 '11 at 01:31
  • 28
    One thing to add is that the args must be a numerical array ([]). Associative arrays ({}) will not work. – Kevin Schroeder Jul 28 '12 at 16:18
  • 347
    @KevinSchroeder: In javascript parlance, `[]` is called an **array**, `{}` is called an **object**. – Martijn Jan 10 '13 at 15:19
  • 93
    I often used to forget which takes an array, and which expects you to list the arguments. A technique I used to remember it is if the first letter of the method starts with **a** then it takes an array i.e **a** pply array – aziz punjani Oct 06 '13 at 20:43
  • 19
    @SAM Using _call_ instead of a normal function call only makes sense if you need to change the value of _this_ for the function call. An example (that convert a functions arguments-object to an array): `Array.prototype.slice.call(arguments)` or `[].slice.call(arguments)`. _apply_ makes sense if you have the arguments in an array, for example in a function that calls another function with (almost) the same parameters. **Recommendation** Use a normal function call `funcname(arg1)` if that does what you need, and save _call_ and _apply_ for those special occasions when you really need them. – some Jul 16 '14 at 05:04
  • 1
    `theFunction.call(undefined, ["Claude", "mathematician"]); // 'My name is Claude,mathematician and I am a undefined.'` Oh Claude! <3 (https://photos-5.dropbox.com/t/1/AABRnQkgeaYomPlRZXK3rX3cc83efluhOVMqei2B3xCkGg/12/781400/png/1024x768/3/1415624400/0/2/Screenshot%202014-11-10%2011.32.52.png/ZxDPt6a1JoHLQz55W1pab-y4cW0tBMZAUHQV2e3i1oQ) – Ralph Cowling Nov 10 '14 at 11:33
  • 1
    theFunction.apply(undefined, ["Susan", "school teacher"]); theFunction.call(undefined, "Claude", "mathematician"); Why the first argument is undefined while calling? – Kunal Singh Aug 27 '15 at 06:40
  • 6
    @KunalSingh Both `call` and `apply` takes two parameters. The first argument of `apply' and `call` function must be the owner object and the second parameter will be array or comma separated parameters respectively. If you pass `null` or `undefined` as first argument then in non-strict mode they are replaced with global object i.e. `window` – A J Qarshi Feb 24 '16 at 12:42
  • # codes bugs ```theFunction.apply(undefined, ...["Matthew", "physicist"]); ``` [A_better_apply](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Spread_operator#A_better_apply) – xgqfrms Dec 25 '16 at 12:07
  • 3
    The mnemonic alone is worth the answer. I don't think I'll need to look it up again! – Álvaro González May 24 '17 at 09:05
  • 2
    @AJQarshi @KunalSingh Just to expound on Qarshi's answer, the first argument, owner object, as he called it, is the execution context you want to pass to the function(`this` context). When an object is passed as argument, then the function invoked is bound to the object's execution context and any reference to members in the function will indeed point to existing object members. Hope this makes sense. – candy_man Jan 05 '18 at 10:26
  • So in regards to JavaScript Proxy and the spread operator, would Handler.Call(target, that, ...args) be the same as Handler.Apply(target, that, args)? – Brain2000 Jul 17 '19 at 15:08
  • You can hear this in every second interview, but I've seen this like once-twice in practice since most of the junior devs don't know this so it would lead just to misunderstandings. – Jakub Kubista Jun 03 '20 at 18:09
241

K. Scott Allen has a nice writeup on the matter.

Basically, they differ on how they handle function arguments.

The apply() method is identical to call(), except apply() requires an array as the second parameter. The array represents the arguments for the target method."

So:

// assuming you have f
function f(message) { ... }
f.call(receiver, "test");
f.apply(receiver, ["test"]);
neoswf
  • 4,269
  • 4
  • 35
  • 52
notnoop
  • 56,619
  • 20
  • 118
  • 142
168

To answer the part about when to use each function, use apply if you don't know the number of arguments you will be passing, or if they are already in an array or array-like object (like the arguments object to forward your own arguments. Use call otherwise, since there's no need to wrap the arguments in an array.

f.call(thisObject, a, b, c); // Fixed number of arguments

f.apply(thisObject, arguments); // Forward this function's arguments

var args = [];
while (...) {
    args.push(some_value());
}
f.apply(thisObject, args); // Unknown number of arguments

When I'm not passing any arguments (like your example), I prefer call since I'm calling the function. apply would imply you are applying the function to the (non-existent) arguments.

There shouldn't be any performance differences, except maybe if you use apply and wrap the arguments in an array (e.g. f.apply(thisObject, [a, b, c]) instead of f.call(thisObject, a, b, c)). I haven't tested it, so there could be differences, but it would be very browser specific. It's likely that call is faster if you don't already have the arguments in an array and apply is faster if you do.

Matthew Crumley
  • 95,375
  • 24
  • 103
  • 125
118

Here's a good mnemonic. Apply uses Arrays and Always takes one or two Arguments. When you use Call you have to Count the number of arguments.

nhahtdh
  • 52,949
  • 15
  • 113
  • 149
Joe
  • 7,646
  • 17
  • 50
  • 82
  • 2
    Useful mnemonic right there!. I will change the 'one or two Arguments' to say 'a maximum of two Arguments' since neither the first or the second parameters of `apply` is required. I'm not sure though why one will call `apply` or `call` without a parameter. Looks like someone is trying to find out why here http://stackoverflow.com/questions/15903782/call-apply-with-no-parameters-vs-simply-calling-a-function-with-paran – dantheta Nov 03 '13 at 11:40
95

While this is an old topic, I just wanted to point out that .call is slightly faster than .apply. I can't tell you exactly why.

See jsPerf, http://jsperf.com/test-call-vs-apply/3


[UPDATE!]

Douglas Crockford mentions briefly the difference between the two, which may help explain the performance difference... http://youtu.be/ya4UHuXNygM?t=15m52s

Apply takes an array of arguments, while Call takes zero or more individual parameters! Ah hah!

.apply(this, [...])

.call(this, param1, param2, param3, param4...)

kmatheny
  • 3,862
  • 1
  • 17
  • 12
  • This depends on what the function does with the parameters/array, if it doesn't need to process the array, does it take less time? – Eric Hodonsky Mar 01 '12 at 20:30
  • 12
    Interestingly even without the array, call is still much faster. http://jsperf.com/applyvscallvsfn2 – Josh Mc May 11 '12 at 01:42
  • @JoshMc That would be very browser specific. In IE 11, I'm getting apply going twice as fast as call. – Vincent McNabb Oct 08 '13 at 01:10
  • 1
    1. Creating a new array means the garbage collector will need to clean it up at some point. 2. Accessing items in the array using dereference is less efficient than accessing a variable (parameter) directly. (I believe that is what kmatheny meant by "parsing", which is actually something quite different.) But neither of my arguments explain the jsperf. That must be related to the engine's implementation of the two functions, e.g. perhaps they create an empty array anyway, if none was passed. – joeytwiddle Nov 23 '13 at 16:41
  • Thank you for sharing the test and video – Gary Jul 23 '17 at 11:22
78

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 Called

When calling a function of the form foo.bar.baz(), the object foo.bar is referred to as the receiver. When the function is called, it is the receiver that is used as the value for this:

var obj = {};
obj.value = 10;
/** @param {...number} additionalValues */
obj.addValues = function(additionalValues) {
  for (var i = 0; i < arguments.length; i++) {
    this.value += arguments[i];
  }
  return this.value;
};
// Evaluates to 30 because obj is used as the value for 'this' when
// obj.addValues() is called, so obj.value becomes 10 + 20.
obj.addValues(20);

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:

var f = obj.addValues;
// Evaluates to NaN because window is used as the value for 'this' when
// f() is called. Because and window.value is undefined, adding a number to
// it results in NaN.
f(20);
// This also has the unintentional side effect of adding a value to window:
alert(window.value); // Alerts NaN

Even though obj.addValues and f 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 to this, it is important to ensure that this will have the correct value when it is called. To be clear, if this were not referenced in the function body, then the behavior of f(20) and obj.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() and apply() which make it possible to redefine the receiver (i.e., the object that this refers to) when calling the function. The method signatures are as follows:

/**
* @param {*=} receiver to substitute for 'this'
* @param {...} parameters to use as arguments to the function
*/
Function.prototype.call;
/**
* @param {*=} receiver to substitute for 'this'
* @param {Array} parameters to use as arguments to the function
*/
Function.prototype.apply;

Note that the only difference between call() and apply() is that call() receives the function parameters as individual arguments, whereas apply() receives them as a single array:

// When f is called with obj as its receiver, it behaves the same as calling
// obj.addValues(). Both of the following increase obj.value by 60:
f.call(obj, 10, 20, 30);
f.apply(obj, [10, 20, 30]);

The following calls are equivalent, as f and obj.addValues refer to the same function:

obj.addValues.call(obj, 10, 20, 30);
obj.addValues.apply(obj, [10, 20, 30]);

However, since neither call() nor apply() uses the value of its own receiver to substitute for the receiver argument when it is unspecified, the following will not work:

// Both statements evaluate to NaN
obj.addValues.call(undefined, 10, 20, 30);
obj.addValues.apply(undefined, [10, 20, 30]);

The value of this can never be null or undefined when a function is called. When null or undefined is supplied as the receiver to call() or apply(), 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 named value 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.

Dominykas Mostauskis
  • 6,521
  • 2
  • 42
  • 58
  • Just to note the fact, that `additionalValues` is not referenced inside `obj.addValues` body – Viktor Stolbin Oct 27 '15 at 12:12
  • I know you were answering the question but would like to add: you could have used bind when defining f. `var f = obj.addValues;` becomes `var f = obj.addValues.bind(obj)` and now f(20) would work without having to use call or apply every time. – jhliberty Oct 25 '17 at 19:15
  • I know you didn't write it, but you did highlight the text and examples from the book as relevant, and I am very grateful. They were very helpful. – Fralcon Feb 07 '20 at 01:14
36

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:

var friend = {
    car: false,
    lendCar: function ( canLend ){
      this.car = canLend;
 }

}; 

var me = {
    car: false,
    gotCar: function(){
      return this.car === true;
  }
};

console.log(me.gotCar()); // false

friend.lendCar.call(me, true); 

console.log(me.gotCar()); // true

friend.lendCar.apply(me, [false]);

console.log(me.gotCar()); // false

These methods are very useful for giving objects temporary functionality.

tjacks3
  • 487
  • 4
  • 5
  • 1
    To people that want to know how to see `console.log` check out: [What is console.log and how do I use it?](http://stackoverflow.com/questions/4743730/what-is-console-log-and-how-do-i-use-it) – Michel Ayres Feb 25 '14 at 19:50
26

Another example with Call, Apply and Bind. The difference between Call and Apply is evident, but Bind works like this:

  1. Bind returns an instance of a function that can be executed
  2. First Parameter is 'this'
  3. Second parameter is a Comma separated list of arguments (like Call)

}

function Person(name) {
    this.name = name; 
}
Person.prototype.getName = function(a,b) { 
     return this.name + " " + a + " " + b; 
}

var reader = new Person('John Smith');

reader.getName = function() {
   // Apply and Call executes the function and returns value

   // Also notice the different ways of extracting 'getName' prototype
   var baseName = Object.getPrototypeOf(this).getName.apply(this,["is a", "boy"]);
   console.log("Apply: " + baseName);

   var baseName = Object.getPrototypeOf(reader).getName.call(this, "is a", "boy"); 
   console.log("Call: " + baseName);

   // Bind returns function which can be invoked
   var baseName = Person.prototype.getName.bind(this, "is a", "boy"); 
   console.log("Bind: " + baseName());
}

reader.getName();
/* Output
Apply: John Smith is a boy
Call: John Smith is a boy
Bind: John Smith is a boy
*/
Mahesh
  • 2,869
  • 1
  • 29
  • 42
23

I'd like to show an example, where the 'valueForThis' argument is used:

Array.prototype.push = function(element) {
   /*
   Native code*, that uses 'this'       
   this.put(element);
   */
}
var array = [];
array.push(1);
array.push.apply(array,[2,3]);
Array.prototype.push.apply(array,[4,5]);
array.push.call(array,6,7);
Array.prototype.push.call(array,8,9);
//[1, 2, 3, 4, 5, 6, 7, 8, 9] 

**details: http://es5.github.io/#x15.4.4.7*

21

Call() takes comma-separated arguments, ex:

.call(scope, arg1, arg2, arg3)

and apply() takes an array of arguments, ex:

.apply(scope, [arg1, arg2, arg3])

here are few more usage examples: http://blog.i-evaluation.com/2012/08/15/javascript-call-and-apply/

Dean Radcliffe
  • 2,154
  • 20
  • 28
Mark Karwowski
  • 589
  • 5
  • 7
  • ` // call() === comma-separated arguments (arguments-list) .call(this, args1, args2, args3, ...) // apply() === array of arguments (array-items) .apply(this, [arr0, arr1, arr2, ...]) ` – xgqfrms Dec 25 '16 at 13:52
19

From the MDN docs on Function.prototype.apply() :

The apply() method calls a function with a given this value and arguments provided as an array (or an array-like object).

Syntax

fun.apply(thisArg, [argsArray])

From the MDN docs on Function.prototype.call() :

The call() method calls a function with a given this value and arguments provided individually.

Syntax

fun.call(thisArg[, arg1[, arg2[, ...]]])

From Function.apply and Function.call in JavaScript :

The apply() method is identical to call(), except apply() requires an array as the second parameter. The array represents the arguments for the target method.


Code example :

var doSomething = function() {
    var arr = [];
    for(i in arguments) {
        if(typeof this[arguments[i]] !== 'undefined') {
            arr.push(this[arguments[i]]);
        }
    }
    return arr;
}

var output = function(position, obj) {
    document.body.innerHTML += '<h3>output ' + position + '</h3>' + JSON.stringify(obj) + '\n<br>\n<br><hr>';
}

output(1, doSomething(
    'one',
    'two',
    'two',
    'one'
));

output(2, doSomething.apply({one : 'Steven', two : 'Jane'}, [
    'one',
    'two',
    'two',
    'one'
]));

output(3, doSomething.call({one : 'Steven', two : 'Jane'},
    'one',
    'two',
    'two',
    'one'
));

See also this Fiddle.

John Slegers
  • 38,420
  • 17
  • 182
  • 152
12

Fundamental difference is that call() accepts an argument list, while apply() accepts a single array of arguments.

Rakesh Kumar
  • 2,648
  • 1
  • 14
  • 32
10

Here's a small-ish post, I wrote on this:

http://sizeableidea.com/call-versus-apply-javascript/

var obj1 = { which : "obj1" },
obj2 = { which : "obj2" };

function execute(arg1, arg2){
    console.log(this.which, arg1, arg2);
}

//using call
execute.call(obj1, "dan", "stanhope");
//output: obj1 dan stanhope

//using apply
execute.apply(obj2, ["dan", "stanhope"]);
//output: obj2 dan stanhope

//using old school
execute("dan", "stanhope");
//output: undefined "dan" "stanhope"
Dan
  • 2,319
  • 4
  • 22
  • 22
  • here is another one: http://blog.i-evaluation.com/2012/08/15/javascript-call-and-apply/ but basically it is right: .call(scope, arg1, arg2, arg3) – Mark Karwowski Jan 21 '14 at 18:07
8

The difference is that call() takes the function arguments separately, and apply() takes the function arguments in an array.

Hkachhia
  • 4,130
  • 5
  • 35
  • 71
Sanjib Debnath
  • 1,912
  • 1
  • 15
  • 14
6

We can differentiate call and apply methods as below

CALL : A function with argument provide individually. If you know the arguments to be passed or there are no argument to pass you can use call.

APPLY : Call a function with argument provided as an array. You can use apply if you don't know how many argument are going to pass to the function.

There is a advantage of using apply over call, we don't need to change the number of argument only we can change a array that is passed.

There is not big difference in performance. But we can say call is bit faster as compare to apply because an array need to evaluate in apply method.

Praveen D
  • 2,258
  • 2
  • 23
  • 40
5

Difference between these to methods are, how you want to pass the parameters.

“A for array and C for comma” is a handy mnemonic.

venkat7668
  • 2,309
  • 1
  • 19
  • 23
  • 12
    What does this answer provide that is not already well-provided in other answers? – Kyll Sep 07 '15 at 10:38
5

Call and apply both are used to force the this value when a function is executed. The only difference is that call takes n+1 arguments where 1 is this and 'n' arguments. apply takes only two arguments, one is this the other is argument array.

The advantage I see in apply over call is that we can easily delegate a function call to other function without much effort;

function sayHello() {
  console.log(this, arguments);
}

function hello() {
  sayHello.apply(this, arguments);
}

var obj = {name: 'my name'}
hello.call(obj, 'some', 'arguments');

Observe how easily we delegated hello to sayHello using apply, but with call this is very difficult to achieve.

Raghavendra
  • 4,929
  • 4
  • 32
  • 49
4

Even though call and apply achive the same thing, I think there is atleast one place where you cannot use call but can only use apply. That is when you want to support inheritance and want to call the constructor.

Here is a function allows you to create classes which also supports creating classes by extending other classes.

function makeClass( properties ) {
    var ctor = properties['constructor'] || function(){}
    var Super = properties['extends'];
    var Class = function () {
                 // Here 'call' cannot work, only 'apply' can!!!
                 if(Super)
                    Super.apply(this,arguments);  
                 ctor.apply(this,arguments);
                }
     if(Super){
        Class.prototype = Object.create( Super.prototype );
        Class.prototype.constructor = Class;
     }
     Object.keys(properties).forEach( function(prop) {
           if(prop!=='constructor' && prop!=='extends')
            Class.prototype[prop] = properties[prop];
     });
   return Class; 
}

//Usage
var Car = makeClass({
             constructor: function(name){
                         this.name=name;
                        },
             yourName: function() {
                     return this.name;
                   }
          });
//We have a Car class now
 var carInstance=new Car('Fiat');
carInstance.youName();// ReturnsFiat

var SuperCar = makeClass({
               constructor: function(ignore,power){
                     this.power=power;
                  },
               extends:Car,
               yourPower: function() {
                    return this.power;
                  }
              });
//We have a SuperCar class now, which is subclass of Car
var superCar=new SuperCar('BMW xy',2.6);
superCar.yourName();//Returns BMW xy
superCar.yourPower();// Returns 2.6
Dhana Krishnasamy
  • 2,051
  • 17
  • 34
  • I believe call would work there with the spread operator as described in the selected answer. Unless I'm missing something. – jhliberty Oct 25 '17 at 19:10
4

The main difference is, using call, we can change the scope and pass arguments as normal, but apply lets you call it using arguments as an Array (pass them as an array). But in terms of what they to do in your code, they are pretty similar.

While the syntax of this function is almost identical to that of apply(), the fundamental difference is that call() accepts an argument list, while apply() accepts a single array of arguments.

So as you see, there is not a big difference, but still, there are cases we prefer using call() or apply(). For example, look at the code below, which finding the smallest and largest number in an array from MDN, using the apply method:

// min/max number in an array
var numbers = [5, 6, 2, 3, 7];

// using Math.min/Math.max apply
var max = Math.max.apply(null, numbers); 
// This about equal to Math.max(numbers[0], ...)
// or Math.max(5, 6, ...)

var min = Math.min.apply(null, numbers)

So the main difference is just the way we passing the arguments:

Call:

function.call(thisArg, arg1, arg2, ...);

Apply:

function.apply(thisArg, [argsArray]);
Alireza
  • 83,698
  • 19
  • 241
  • 152
4

Summary:

Both call() and apply() are methods which are located on Function.prototype. Therefore they are available on every function object via the prototype chain. Both call() and apply() can execute a function with a specified value of the this.

The main difference between call() and apply() is the way you have to pass in arguments into it. In both call() and apply() you pass as a first argument the object you want to be the value as this. The other arguments differ in the following way:

  • With call() you have to put in the arguments normally (starting from the second argument)
  • With apply() you have to pass in array of arguments.

Example:

let obj = {
  val1: 5,
  val2: 10
}

const summation = function (val3, val4) {
  return  this.val1 + this.val2 + val3 + val4;
}

console.log(summation.apply(obj, [2 ,3]));
// first we assign we value of this in the first arg
// with apply we have to pass in an array


console.log(summation.call(obj, 2, 3));
// with call we can pass in each arg individually

Why would I need to use these functions?

The this value can be tricky sometimes in javascript. The value of this determined when a function is executed not when a function is defined. If our function is dependend on a right this binding we can use call() and apply() to enforce this behaviour. For example:

var name = 'unwantedGlobalName';

const obj =  {
  name: 'Willem',
  sayName () { console.log(this.name);}
}


let copiedMethod = obj.sayName;
// we store the function in the copiedmethod variable



copiedMethod();
// this is now window, unwantedGlobalName gets logged

copiedMethod.call(obj);
// we enforce this to be obj, Willem gets logged
Willem van der Veen
  • 19,609
  • 11
  • 116
  • 113
2

Let me add a little detail to this.

these two calls are almost equivalent:

func.call(context, ...args); // pass an array as list with spread operator

func.apply(context, args);   // is same as using apply

There’s only a minor difference:

  • The spread operator ... allows passing iterable args as the list to call.
  • The apply accepts only array-like args.

So, these calls complement each other. Where we expect an iterable, call works, where we expect an array-like, apply works.

And for objects that are both iterable and array-like, like a real array, we technically could use any of them, but apply will probably be faster because most JavaScript engines internally optimize it better.

Pravin Divraniya
  • 3,642
  • 2
  • 26
  • 45
1

call() It’s a predefined method in javascript. This method invokes a method (function) by specifying the owner object.

  function sayHello(){
  return "Hello " + this.name;
}
        
var obj = {name: "Sandy"};
        
sayHello.call(obj);
        
// Returns "Hello Sandy"

Call accepts argument

function saySomething(message){
  return this.name + " is " + message;
}
        
var person4 = {name:  "John"};
        
saySomething.call(person4, "awesome");
// Returns "John is awesome"    

apply() The apply method is similar to the call() method. The only difference is that, call() method takes arguments separately whereas, apply() method takes arguments as an array.

example

function saySomething(message){
  return this.name + " is " + message;
}
        
var person4 = {name:  "John"};
        
saySomething.apply(person4, ["awesome"]);
bisma
  • 305
  • 3
  • 7
0

A well explained by flatline. I just want to add a simple example. which makes it easy to understand for beginners.

func.call(context, args1 , args2 ); // pass arguments as "," saprated value

func.apply(context, [args1 , args2 ]);   //  pass arguments as "Array"

we also use "Call" and "Apply" method for changing reference as defined in code below

    let Emp1 = {
        name: 'X',
        getEmpDetail: function (age, department) {
            console.log('Name :', this.name, '  Age :', age, '  Department :', department)
        }
    }
    Emp1.getEmpDetail(23, 'Delivery')

    // 1st approch of chenging "this"
    let Emp2 = {
        name: 'Y',
        getEmpDetail: Emp1.getEmpDetail
    }
    Emp2.getEmpDetail(55, 'Finance')

    // 2nd approch of changing "this" using "Call" and "Apply"
    let Emp3 = {
        name: 'Z',
    }

    Emp1.getEmpDetail.call(Emp3, 30, 'Admin')        
// here we have change the ref from **Emp1 to Emp3**  object
// now this will print "Name =  X" because it is pointing to Emp3 object
    Emp1.getEmpDetail.apply(Emp3, [30, 'Admin']) //
0

The call() method calls a function with a given this value and arguments provided individually.enter image description here

apply() - Similar to the call() method, the first parameter in the apply() method sets the this value which is the object upon which the function is invoked. In this case, it's the obj object above. The only difference between the apply() and call() method is that the second parameter of the apply() method accepts the arguments to the actual function as an array. enter image description here

unsuredev
  • 71
  • 2
  • 10
  • 1
    Although we appreciate the effort you did making images, they are not very useful. Nobody can copy the code to use, test, improve... The code should be pasted as text here – Vega Jun 25 '20 at 17:57
0

Both call and apply the same way. It calls immediately when we use call and apply.

Both call and apply takes "this" parameter as the first argument and the second argument only differs.

the call takes the arguments of the functions as a list (comma ) Apply takes the arguments of the functions as an array.

You can find the complete difference between bind, call, and apply in the bellow youtube video.

https://www.youtube.com/watch?v=G-EfxnG0DtY&t=180s