fn.apply()
vs fn.call()
in JavaScript + better alternative
Published on in JavaScript and Mnemonics
Last updated on
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.
A note about verbosity
This is not verbose:
foo.apply(thisArg, [1, 2, 3])
But it's not safe either as stated above.
This is safe but also verbose:
Function.prototype.apply.call(foo, thisArg, [1, 2, 3])
Now it's easy to see
why Reflect.apply()
is "arguably less verbose and easier to understand":
Reflect.apply(foo, thisArg, [1, 2, 3])