apply
function calls a function with a given context (this) and arguments passed as a list (array). It is defined on the prototype of Function class. It is similar to call function in JavaScript except how it takes the arguments.
Function.prototype.apply
If the context is passed as null or undefined to apply
then the function will be executed in the global context (window in the browser and global in node.js).
If the arguments passed is not an array, then the apply
function will throw a type error CreateListFromArrayLike called on non-object.
Syntax
apply(thisArg, [arg1, …, argN])
- thisArg – Optional – Value to be used as this (context) while calling the function.
- [arg1, …, argN] – Optional – Array of arguments to be passed in the function.
Examples
function greet(to, from) {
console.log(`Hello ${to}, I am ${from}`);
}
greet();
greet.apply(null, ['Tony', 'Steve']);
Hello undefined, I am undefined Hello Tony, I am Steve
const heroNickNames = {
hulk: 'Green Goliath',
spiderMan: 'Spidey',
thor: 'Goldilocks'
};
function printHeroNickNames() {
console.log(`
Nick names of heroes:
Hulk - ${this.hulk}
SpiderMan - ${this.spiderMan}
Thor - ${this.thor}
`);
}
printHeroNickNames();
printHeroNickNames.apply(heroNickNames);
Nick names of heroes: Hulk - undefined SpiderMan - undefined Thor - undefined Nick names of heroes: Hulk - Green Goliath SpiderMan - Spidey Thor - Goldilocks
// Using 'apply' to concatenate arrays
const firstArray = [1, 2, 3, 4];
const secondArray = [5, 6, 7, 8, 9];
firstArray.push.apply(firstArray, secondArray);
console.log(firstArray);
[ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
Can we write our own “apply” function?
Now that we have spread (…) operator in JavaScript, let’s try to write our own implementation of apply
.
Function.prototype.myApply = function (thisArg, args) {
if (thisArg === null || thisArg === undefined) {
thisArg = globalThis;
}
if (!Array.isArray(args)) {
throw new Error('Argument must be an array');
}
const newFunction = this.bind(thisArg);
return newFunction(...args);
}
const avengersTower = {
availableHero: 'Hulk'
};
function assistHeroes(heroOne, heroTwo) {
console.log(`${heroOne} and ${heroTwo} will be assisted by currently available hero: ${this.availableHero}`);
}
assistHeroes('AntMan', 'Hawkeye');
assistHeroes.myApply(avengersTower, ['AntMan', 'Hawkeye']);
AntMan and Hawkeye will be assisted by currently available hero: undefined AntMan and Hawkeye will be assisted by currently available hero: Hulk
Explanation
- Define a new function on prototype of Function class. We are doing this because we want our function to be available on functions rather taking them as argument.
- Check thisArg. Assign [globalThis] to thisArg if found [null] or [undefined].
- Check if the argument provided is an array or not.
- Get a new function bounded with new context (thisArg).
- Execute the new function by spreading the arguments and return the result.