Q13: Implement a polyfill for Function.prototype.apply().
Answer
The apply() method invokes a function immediately with a specified this value and arguments supplied as an array or array-like object.
Function.prototype.myApply = function (thisArg, argsArray) {
if (typeof this !== "function") {
throw new TypeError("myApply must be called on a function");
}
const fn = this;
const context = thisArg == null ? globalThis : Object(thisArg);
const key = Symbol("fn");
const args = argsArray == null ? [] : Array.from(argsArray);
context[key] = fn;
try {
return context[key](...args);
} finally {
delete context[key];
}
};
function add(a, b, c) {
return this.base + a + b + c;
}
console.log(add.myApply({ base: 10 }, [1, 2, 3]));
// 16
Explanation
The implementation follows the same temporary-property technique as the call() polyfill. The difference is that apply() accepts a single argument collection instead of separate arguments.
Array.from() supports common array-like objects and iterables. Native apply() has specific behavior for its arguments list and does not simply call Array.from() on every supplied value, so this is an interview-oriented approximation.
Key Takeaways
- Apply invokes the function immediately with arguments from an array-like collection.
- Call and apply differ mainly in how their arguments are supplied.