Skip to main content

Function Methods

Function.call

Function.prototype.myCall = function (thisArg, ...args) {
// The "this" in this execution context refers to the function that calls myCall

// Create a unique key using symbol to avoid overriding keys on thisArg
const symbol = Symbol();

// Add "this" to thisArg
thisArg[symbol] = this;

// Invoke the function stored on thisArg and store its return value.
const output = thisArg[symbol](...args);

// Since we modified the passed thisArg, we need to restore it to its original state.
delete thisArg[symbol];

return output;
};

Function.apply

Function.prototype.myApply = function (thisArg, args = []) {
return this.myCall(thisArg, ...args);
};

Function.bind

Function.prototype.myBind = function (thisArg, ...args) {
// An arrow function is used here
// because using a regular function would create a new "this" that points to the global object
// Arrow functions don't have their own "this" binding
// instead, they inherit "this" through the scope chain from the function that calls myBind
return (...newArgs) => this.myApply(thisArg, [...args, ...newArgs]);
};