Q12: Implement a polyfill for Function.prototype.call().

Difficulty:IntermediateTopic:Function Methods

Answer

The call() method invokes a function immediately with a specified this value and individual arguments.

Function.prototype.myCall = function (thisArg, ...args) {
  if (typeof this !== "function") {
    throw new TypeError("myCall must be called on a function");
  }

  const fn = this;
  const context = thisArg == null ? globalThis : Object(thisArg);
  const key = Symbol("fn");

  context[key] = fn;

  try {
    return context[key](...args);
  } finally {
    delete context[key];
  }
};

function greet(greeting, punctuation) {
  return `${greeting}, ${this.name}${punctuation}`;
}

const person = { name: "Suriya" };

console.log(greet.myCall(person, "Hello", "!"));
// Hello, Suriya!

Explanation

  1. Capture the function as this inside myCall.
  2. Convert the supplied receiver into an object, except for nullish values, which use globalThis in this simplified implementation.
  3. Attach the function temporarily under a unique symbol.
  4. Invoke it as a method so the receiver becomes its this value.
  5. Delete the temporary property in a finally block.

Important limitation: This technique is an interview approximation, not a fully specification-compliant polyfill. Native call() treats nullish receivers differently in strict and non-strict functions. This implementation also cannot reproduce every behavior of native call, especially for all exotic receivers and functions.

Key Takeaways
  • Call invokes a function immediately with a specified receiver and separate arguments.
  • Temporary symbol properties are a common interview technique, but not an exact replacement for the native method.