Function prototype – JavaScript Challenges



This content originally appeared on DEV Community and was authored by Mitchell

You can find all the code in this post at repo Github.

Function prototype related challenges

Function.prototype.call()

/**
 * @param {any} thisArg
 * @param {...*} argArray
 * @return {any}
 */

Function.prototype.myCall = function (thisArg, ...argArray) {
  const sym = Symbol();
  const wrapperObj = Object(thisArg);

  Object.defineProperty(wrapperObj, sym, {
    enumerable: false,
    value: this,
  });

  return wrapperObj[sym](...argArray);
};

// Usage example
function multiplyAge(multiplier = 1) {
  return this.age * multiplier;
}

const mary = {
  age: 21,
};

const john = {
  age: 42,
};

console.log(multiplyAge.myCall(mary)); // 21
console.log(multiplyAge.myCall(john, 2)); // 84

Function.prototype.apply()

/**
 * @param thisArg The object to be used as the this object.
 * @param argArray A set of arguments to be passed to the function.
 * @return {any}
 */

Function.prototype.myApply = function (thisArg, argArray = []) {
  const sym = Symbol();
  const wrapperObj = Object(thisArg);

  Object.defineProperty(wrapperObj, sym, {
    enumerable: false,
    value: this,
  });

  return wrapperObj[sym](...argArray);
};

// Usage example
function multiplyAge(multiplier = 1) {
  return this.age * multiplier;
}

const mary = {
  age: 21,
};

const john = {
  age: 42,
};

console.log(multiplyAge.myApply(mary)); // 21
console.log(multiplyAge.myApply(john, [2])); // 84

Function.prototype.bind()

/**
 * @param {any} thisArg
 * @param {...*} argArray
 * @return {Function}
 */

Function.prototype.myBind = function (thisArg, ...argArray) {
  const sym = Symbol();
  const wrapperObj = Object(thisArg);

  Object.defineProperty(wrapperObj, sym, {
    enumerable: false,
    value: this,
  });

  return function (...args) {
    return wrapperObj[sym](...argArray, ...args);
  };
};

// Usage example
const john = {
  age: 42,
  getAge: function () {
    return this.age;
  },
};

const unboundGetAge = john.getAge;
console.log(unboundGetAge()); // undefined

const boundGetAge = john.getAge.myBind(john);
console.log(boundGetAge()); // 42

const jack = {
  age: 21,
  getAge: function () {
    return this.age;
  },
};

// For multiple `.bind()` chaining, only the first one would work
const boundJohnGetAge = john.getAge.myBind(john).myBind(jack);
console.log(boundGetAge()); // 42

Reference


This content originally appeared on DEV Community and was authored by Mitchell