JavaScript: fn.apply() vs fn.call() + better alternative

Mnemonic: "a" (apply()) for an array, "c" (call()) for commas. But Reflect.apply() is better.

Table of contents

fn.apply() vs fn.call()

The apply() method takes arguments as an array, and the call() method takes multiple arguments:

function foo() {}

const thisArg = {}
const args = [1, 2, 3]

foo.apply(thisArg, args)
foo.apply(thisArg, [1, 2, 3])

foo.call(thisArg, ...args)
foo.call(thisArg, 1, 2, 3)

Mnemonic: a (apply()) for an array, c (call()) for commas.

Source for the mnemonic: What is the difference between call and apply? on Stack Overflow.

The better alternative

Reflect.apply() is better. Like fn.apply(), it takes arguments as an array:

function foo() {}

const thisArg = {}
const args = [1, 2, 3]

Reflect.apply(foo, thisArg, args)
Reflect.apply(foo, thisArg, [1, 2, 3])

It's "arguably less verbose and easier to understand" than fn.apply(). "In addition, when you accept arbitrary methods, it's not safe to assume .apply() exists or is not overridden."

Source: Prefer Reflect.apply() over Function#apply() ESLint rule from eslint-plugin-unicorn.

Further resources