Compile Ready
Module 7 · The this Keyword

Function.prototype.apply

Intermediate8m read6m practice14m total
thisapplyExplicit BindingArguments

Introduction

Function.prototype.apply invokes a function immediately with a specific this value and an array-like list of arguments: fn.apply(thisArg, argsArray).

It is the sibling of call. Use call when arguments are already separate; use apply when arguments are already collected.

Why This Matters

apply appears in legacy JavaScript, polyfills, function forwarding, and many interview implementations. Even though spread syntax replaced some common uses, apply remains essential for understanding how bind and function delegation work.

Theory

Syntax

fn.apply(thisArg, argsArray)

apply does two things:

  1. Invokes fn immediately.
  2. Expands argsArray into positional arguments while binding this to thisArg for regular functions.

call vs apply

ToolArgument styleTiming
callfn.call(obj, a, b)Immediate
applyfn.apply(obj, [a, b])Immediate
bindfn.bind(obj, a)Later

Forwarding arguments

apply is especially useful when writing wrappers. If a wrapper receives an array of values and needs to forward them to another function, apply avoids manually indexing each one.

Modern spread comparison

fn.apply(obj, args) is similar to fn.call(obj, ...args), but apply works directly with array-like values in older code. Modern code often uses spread for arrays, but interviews still ask apply because it reveals explicit binding mechanics.

Arrow caveat

Like call, apply cannot change an arrow function's lexical this.

Visual Diagrams

apply expands an argument list
calculate.apply(invoice, [2, 5, 1])
      |       |        |
      |       |        +-- array-like arguments
      |       +----------- thisArg
      +------------------- function to invoke now

Inside calculate:
  this === invoice
  first arg === 2
  second arg === 5
  third arg === 1

`apply` is explicit binding plus argument-list expansion.

Code Examples

Forward a collected argument list

Wrappers often receive arguments as an array and forward them with apply.

Loading…

Legacy maximum with apply

Before spread syntax, apply was the common way to pass an array to a variadic function.

Loading…

Playground

Loading editor…
Console

Press Run to execute the code and see output here.

Output Prediction

Predict the output #1

javascript
1function multiply(a, b) {
2 console.log(this.factor * a * b);
3}
4
5const context = { factor: 3 };
6multiply.apply(context, [2, 5]);

Predict the output #2

javascript
1function joinThree(a, b, c) {
2 console.log(this.prefix + a + b + c);
3}
4
5joinThree.apply({ prefix: 'id-' }, [1, 2, 3]);

Coding Exercises

Implement an argument-forwarding wrapper

Medium

Implement withReceiver(fn, receiver) so it returns a function that accepts an array of arguments and invokes fn with receiver as this. Use apply.

Interview Questions

1What is the difference between `call` and `apply`?

Both invoke a function immediately with an explicit this value. call takes arguments one by one: fn.call(obj, a, b). apply takes a single array-like argument list: fn.apply(obj, [a, b]).

Asked at:AmazonMicrosoftGoogle
2When is `apply` useful in modern JavaScript?

It is useful for forwarding a collected argument list, writing wrappers, maintaining legacy code, and understanding polyfills such as simplified bind. Modern spread syntax covers many array use cases, but apply is still the explicit-binding primitive for array-like forwarding.

Quiz

1. Which expression calls `fn` with `obj` as `this` and `[1, 2]` as the argument list?

2. What is the timing difference between `apply` and `bind`?

Summary

  • `apply` invokes a function immediately with explicit `this`.
  • The second argument to `apply` is an array-like list of arguments.
  • `apply` is ideal for forwarding collected arguments.
  • Modern spread replaces some uses but not the underlying concept.
  • Arrow functions ignore `apply` for `this` binding.

Cheat Sheet

Syntax: fn.apply(thisArg, argsArray).

Timing: immediate invocation.

Arguments: collected array-like list.

Use cases: wrappers, argument forwarding, legacy variadic calls.

Compare: call takes separate args; bind returns a later function.