Q12: Implement a polyfill for Function.prototype.call().
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
- Capture the function as
thisinsidemyCall. - Convert the supplied receiver into an object, except for nullish values, which use
globalThisin this simplified implementation. - Attach the function temporarily under a unique symbol.
- Invoke it as a method so the receiver becomes its
thisvalue. - Delete the temporary property in a
finallyblock.
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.