Function.prototype.callLoading saved progress…

Function.prototype.call

Implement Function.prototype.myCall — a from-scratch version of Function.prototype.call. Given any function, fn.myCall(thisArg, ...args) invokes the function immediately with thisArg as its this and args spread out as the arguments.

This is the runtime hook the language uses for method borrowingArray.prototype.slice.call(arguments) is the classic example. You're rebuilding that hook by hand.

Signature

// Installed on Function.prototype.
fn.myCall(thisArg: any, ...args: any[]): any
//   ^ invokes fn immediately with `this === thisArg` and arguments === args

Examples

function greet(greeting, name) {
  return `${greeting}, ${name}! I am ${this.role}.`;
}
greet.myCall({ role: 'admin' }, 'Hi', 'Ana');
// → "Hi, Ana! I am admin."
// Method borrowing — the canonical use case.
const arrayLike = { 0: 'a', 1: 'b', length: 2 };
Array.prototype.slice.myCall(arrayLike);
// → ['a', 'b']
// thisArg is forwarded verbatim — null/undefined just pass through.
function readType() { return typeof this; }
readType.myCall(null);
// → 'object' in sloppy mode (boxed to global), 'undefined' in strict

Notes

  • Invoke immediately — unlike bind, call runs the function right now and returns its result. Nothing is deferred.
  • thisArg wins for this one call — set this for the invocation; don't permanently bind it.
  • Args spread positionallyfn.myCall(t, 1, 2, 3) is fn(1, 2, 3) with this === t. No array packing.
  • null / undefined are passed through as-is. Don't special-case them; the underlying invocation does the right thing per its own mode.
  • Don't mutate the host object permanently. The trick involves attaching the function as a temporary property — you MUST clean up after the call.
  • Function.prototype.call, .apply, and .bind are off-limits. The whole point is to reproduce the this-binding from primitives.
Loading editor…