Implement Function.prototype.apply
`apply` and `call` differ in exactly one way: `call` takes its arguments individually, `apply` takes them as one array. That means `myApply` can be built as a one-line wrapper over the real `call` — spread the array back into individual arguments. The only thing worth being careful about is that the array argument is optional.
The problem
Implement `Function.prototype.myApply(thisArg, argArray)` so that `fn.myApply(obj, args)` invokes `fn` with `this` bound to `obj` and called with the elements of `args` as its arguments — without using the native `apply`.
`argArray` is optional: `multiplyAge.myApply(mary)` must work with no array at all, just like real `apply` does, falling back to whatever the function's own default parameters provide.
The approach
Since `call` already does the `this`-binding half of the job and only differs from `apply` in how the argument list is shaped, the whole implementation is `this.call(thisArg, ...argArray)` — spreading the array turns it into the individual arguments `call` expects.
The one trap: `argArray` can be `undefined` when the caller omits it, and spreading `undefined` throws. Default it to an empty array — `argArray ?? []` — before spreading, so the no-array call falls through cleanly to the target function's own default parameters.
The solution
/**
* @this {(...args: Array<unknown>) => unknown}
* @param {unknown} thisArg
* @param {Array<unknown>} [argArray]
* @returns {unknown}
*/
Function.prototype.myApply = function (thisArg, argArray) {
return this.call(thisArg, ...(argArray ?? []));
};Time O(n)Space O(n)