Understanding prototype.apply() in JavaScript

Hero image for Understanding prototype.apply() in JavaScript. Image by Steve Johnson.
Hero image for 'Understanding prototype.apply() in JavaScript.' Image by Steve Johnson.

In JavaScript, Function.prototype.apply() is a method which plays a crucial role in objectoriented, functional programming. This method allows for dynamic invocation of functions and provides flexibility in the way that arguments are passed to these functions.

Here, I intend to discuss this in detail, explore apply(), and describe how it is used in scenarios where it becomes particularly useful.


What is prototype.apply()?

Function.prototype.apply() is a method that calls a function with a given this value and arguments provided as an array (or an arraylike object). It is similar to Function.prototype.call(), but the way arguments are passed is different.

Syntax

func.apply(thisArg, [argsArray])
  • func: The function to be called.
  • thisArg: The value of this provided for the call to func.
  • argsArray: An array or arraylike object specifying the arguments to pass to func.

Using apply() in JavaScript

A Basic Example

const greet = (subject) => {  console.log(`Hello, ${subject}!`);};greet.apply(null, ['World']);  //=> "Hello, World!"

Admittedly it's a very basic example, but here we're using apply() to call the greet function whilst setting this to null (indicating the global context in nonstrict mode) and passing the argument in an array.

Just to add to the confusion a tiny bit, the null argument for thisArg in apply() has no effect in this particular context since arrow functions don't have their own this binding anyway.


Why and When to Use apply()

  • Dynamic Function Invocation

    : apply() is useful when the number of arguments to pass to the function is not known until runtime.
  • Working with Arraylike Objects

    : It's handy for functions that accept an array of arguments, especially when dealing with arraylike objects (like arguments in a function).
  • Borrowing Methods

    : apply() allows an object to use a method belonging to another object, which is a powerful feature for method borrowing.

A More in‑Depth Example

I tend to find that borrowing methods makes up a significant chunk of my personal use of apply(), so to offer a slightly more indepth example:

const person = {  name: 'Maddie',  introduce() {    console.log(`Hello, my name is ${this.name}`);  },};const anotherPerson = { name: 'Brian' };person.introduce.apply(anotherPerson);  //=> "Hello, my name is Brian"

Here, anotherPerson borrows the introduce method from person using apply().


Differences from call()

Although .apply() is similar to call() (which you can read about in more detail here), the key difference is in how arguments are passed:

  • call() accepts an argument list.
  • apply() accepts a single array of arguments.

Everything else being equal (and we'll get to that in a minute), choosing between call() and apply() typically depends on the format in which arguments are available.


Use Cases in Modern JavaScript

Really, this article is a few years too late. With the spread operator (...) available in ES6, the necessity of apply() for spreading array arguments has gone. Now, you can now use call() with spread syntax to achieve essentially the same thing. However, apply() remains useful in cases where the arraylike object isn't a proper array, or if you're working with an older JavaScript codebase.


Wrapping up

Function.prototype.apply() is a versatile method in JavaScript, which enables dynamic function invocation and method borrowing across different objects. Understanding apply() adds to your developer toolkit, especially in scenarios involving complex object manipulations or where arguments to a function are determined at runtime.


Categories:

  1. Adaptive Development
  2. Cross‑Browser Compatibility
  3. Front‑End Development
  4. Guides
  5. JavaScript
  6. Responsive Development