Function.prototype.apply
Function.prototype.apply calls a function with an explicitly specified context (this), passing the arguments to it as an array. It is the close sibling of the call method, and the only difference between them is the way arguments are passed.
Theory
TL;DR
applyinvokes the function immediately and lets you setthismanually.- Arguments are passed as an array or an array-like object, not as a comma separated list.
calldoes the same thing, but its arguments are listed one by one.bindinvokes nothing: it only returns a new function with a boundthis.- Classic uses:
Math.max.apply(null, nums)and borrowing array methods forarguments. - The modern replacement in many cases is the spread syntax,
func(...args).
Quick example
function sum(a, b, c) {
return a + b + c;
}
const numbers = [1, 2, 3];
// the arguments are already in an array, so apply fits perfectly
console.log(sum.apply(null, numbers)); // 6Syntax
func.apply(thisArg, [argsArray])thisArgis the object that becomesthisinside the function;argsArrayis an array (or an array-like object) of arguments.
Basic use with an explicit context:
function greet(city, job) {
console.log(`I am ${this.name} from ${city}, working as a ${job}`);
}
const user = { name: 'Maria' };
greet.apply(user, ['Kyiv', 'Frontend developer']);
// I am Maria from Kyiv, working as a Frontend developerThe same thing via call:
greet.call(user, 'Kyiv', 'Frontend developer');The difference is only in how the arguments are passed:
call-> comma separated,apply-> as an array.
Working with array-like objects
apply is often used when the arguments are already stored in an array or a similar structure (arguments, NodeList and so on). That makes it possible to borrow an array method for an object that has no array methods of its own:
function logArgs() {
console.log(arguments);
// turn arguments into an array with Array.prototype.slice
const arr = Array.prototype.slice.apply(arguments);
console.log(arr);
}
logArgs(1, 2, 3, 4);
// arguments -> [1, 2, 3, 4]Here apply lets you call an array method (slice) on the arguments object, which is not an array but does have length and numeric indices.
Math.max and Math.min via apply
Math.max and Math.min do not accept an array, only a list of numbers. apply solves this elegantly:
const nums = [10, 20, 5, 40];
console.log(Math.max.apply(null, nums)); // 40
console.log(Math.min.apply(null, nums)); // 5The ES6 equivalent:
Math.max(...nums); // modern spread syntaxapply vs call and bind
| Method | What it does | How arguments are passed | When it runs |
|---|---|---|---|
| call | Calls the function with the given this | Comma separated | Immediately |
| apply | Calls the function with the given this | As an array | Immediately |
| bind | Creates a new function with a bound this | Comma separated | Later (when called) |
Summary of apply:
| Property | Description |
|---|---|
| Purpose | Call a function with a given this |
| Argument passing | An array or an array-like object |
| Execution context | Global or set manually |
| When to use it | When the arguments are already collected in an array |
| Modern alternative | func(...args) (spread syntax) |
Details of thisArg
If thisArg is null or undefined, then:
- in strict mode (
'use strict') ->this = undefined; - in sloppy mode ->
this = window(orglobalin Node.js).
function showThis() {
console.log(this);
}
showThis.apply(null); // window (in sloppy mode)That is exactly why examples such as Math.max.apply(null, nums) safely pass null first: those functions do not need a context at all.
Common mistakes
- Mixing up
callandapply.applyexpects one array, sosum.apply(null, 1, 2, 3)will not work, whilesum.call(null, [1, 2, 3])passes the array as the first argument. - Assuming
applyreturns a new function. That is whatbinddoes;applyexecutes the function right away and returns its result. - Counting on a global
thisin strict mode. Modules and classes run in strict mode, so withnullthethisstaysundefined. - Passing a very large array into
apply. Every element becomes a separate argument, so with arrays of hundreds of thousands of items you can hitRangeError: Maximum call stack size exceeded. - Trying to construct an object with
apply.applydoes not work withnew: to call a constructor with an array of arguments you needReflect.construct(Ctor, args)ornew Ctor(...args).
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.