Function.prototype.apply implementation
What is apply method
According to MDN docs the apply() method of Function instances calls this function with a given this value, and arguments provided as an array (or an array-like object).
Args
- It takes the
thisArgas the first argument - An array-like object, specifying the arguments with which func should be called, or null or undefined if no arguments should be provided to the function.
Return value
- The result of calling the function with the specified this value and arguments.
Note
This function is almost identical to call(), except that the function arguments are passed to call() individually as a list, while for apply() they are combined in one object, typically an array.
Syntax:
apply(thisArg)
apply(thisArg, argArr)example -
function multiplyAge(multiplier = 1) {
return this.age * multiplier;
}
const mary = {
age: 21,
};
const john = {
age: 42,
};
multiplyAge.myApply(mary); // 21
multiplyAge.myApply(john, [2]); // 84
Implementation of our own apply method -
1. Implementing using bind method
Function.prototype.myApply = function(thisArg, args = []) {
const originalFn = this;
return originalFn.bind(thisArg)(...args);
}2. Implementing using Symbol
What if we don't want to use bind method?
If we carefully see what bind method do is it bound the environment of original function within the thisArg passed to it and return a new function which when called with arguments calls the original function within that environment with the arguments provided.
We can implement this functionality using Symbol.
Symbol would help us get the key which would be unique and do not clash with any existing properties on the object.
Function.prototype.myApply = function(thisArg, args = []) {
const originalFn = this;
// A unique symbol is created to use as a temporary property name.
// Symbols are unique and do not clash with any existing properties on the object.
const key = Symbol('func');
let ctx = thisArg ?? window;
// This ensures that ctx is always an object.
// If a primitive value (like a string or number) is passed, it is converted to its corresponding object type
ctx = Object(ctx);
ctx[key] = originalFn;
// This allows the original function to be executed with ctx as its context.(added temporarily)
const response = ctx[key](...args);
delete ctx[key];
return response;
}Info
You can read more about Function.prototype.apply() on mdn docs here