Skip to main content

call vs apply

call and apply invoke a function with an explicitly specified this context, and they differ only in how the arguments are passed: call takes them comma separated, apply takes them as a single array. The return value, the moment of the call and the behaviour of this are identical in both.

Theory

TL;DR

  • Both methods invoke the function immediately and return its result.
  • The first argument of both is thisArg, the call context.
  • call -> arguments comma separated: func.call(thisArg, arg1, arg2, arg3).
  • apply -> arguments as an array: func.apply(thisArg, [arg1, arg2, arg3]).
  • Arguments known up front -> call; arguments already in an array -> apply.
  • In modern JavaScript both are often replaced by the spread operator: func(...args).

Quick example

MethodHow arguments are passedCall example
calllisted comma separatedfunc.call(thisArg, arg1, arg2, arg3)
applypassed as an arrayfunc.apply(thisArg, [arg1, arg2, arg3])
javascript
function greet(city, job) { console.log(`I am ${this.name} from ${city}, working as a ${job}`); } const user = { name: 'Maria' }; // call: arguments comma separated greet.call(user, 'Kyiv', 'Frontend developer'); // apply: arguments as an array greet.apply(user, ['Kyiv', 'Frontend developer']);

Both calls print the same thing:

I am Maria from Kyiv, working as a Frontend developer

When to use which

ScenarioBetter choice
The arguments are known in advancecall
The arguments are already in an arrayapply

An example with an array of arguments:

javascript
function sum(a, b, c) { return a + b + c; } const nums = [1, 2, 3]; // without apply you would have to unpack the array by hand console.log(sum.call(null, nums[0], nums[1], nums[2])); // with apply you simply pass the array console.log(sum.apply(null, nums)); // 6

The longer the array, the clearer the advantage of apply: unpacking ten elements by hand through call is impossible when the length is not known in advance.

The modern spread equivalent

In modern versions of JavaScript (ES6+) apply is often replaced by the spread operator:

javascript
const nums = [1, 2, 3]; console.log(sum(...nums)); // the same result as sum.apply(null, nums)

Spread reads more simply and does not require an artificial null context. apply is still appropriate when this really has to be substituted, for example fn.apply(ctx, args), or in legacy code without ES6 support.

Summary table

Propertycallapply
Context (this)Explicitly given as the first argumentThe same
Argument passingComma separatedAs an array
ReturnsThe function resultThe function result
Invokes immediatelyYesYes
Modern alternativeSpread: func(...args)Spread: func(...args)

Common mistakes

  • Passing an array into call. sum.call(null, [1, 2, 3]) hands the array over as the first parameter a, so the result is "1,2,3undefinedundefined" instead of 6.
  • Listing arguments in apply. sum.apply(null, 1, 2, 3) ignores everything after the second parameter: apply reads only one array.
  • Confusing them with bind. call and apply invoke the function right away, while bind only returns a new function that has to be called separately.
  • Forgetting about thisArg. The first argument is mandatory by position: when no context is needed you pass null rather than skipping it.
  • Expecting different performance. There is essentially no difference; choosing between call and apply is a matter of convenience, not speed.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.