Implementing call, apply, and bind from scratch is one of the most common frontend interview questions. It tests whether you truly understand how this works — not just the rules, but the mechanics.
What are call(), apply(), and bind()?
These three methods let you explicitly control what this refers to when a function executes. By default, this is determined by how a function is called (the "implicit binding" rule) — but call, apply, and bind override that.
call(thisArg, ...args)— invokes the function immediately withthisset tothisArgand arguments passed individually.apply(thisArg, argsArray)— same ascall, but arguments are passed as an array (or array-like object).bind(thisArg, ...args)— does NOT invoke the function. It returns a new function withthispermanently bound tothisArg, with optional partial application of arguments.
These are foundational because many higher-level patterns (function borrowing, partial application, method delegation) are built on them. In modern code, arrow functions and the ...spread operator handle some of these use cases, but bind is still essential for event handlers and callback binding.
The core mechanic behind all three is the temporary property trick: attach the function as a property on the context object, call it as obj.fn(), then remove the property. Implicit binding handles the rest.
The Problem
Interviewers will ask some variation of:
"Implement Function.prototype.myCall, myApply, and myBind from scratch. Each should replicate the behavior of the native method."
You're expected to implement all three. The interviewer may start with call and ask you to build up to bind.
Thought Process
The core question is: how do you make this point to a specific object when calling a function?
Recall the implicit binding rule: when a function is called as obj.fn(), this inside fn is obj. So the trick is:
- Temporarily attach the function as a property on the context object
- Call it as
obj[tempKey]()— implicit binding setsthis - Delete the temporary property
That's the entire mechanical insight. Everything else is edge cases and argument forwarding.
Step 1 — myCall: Base Implementation
Loading editor...
Why Symbol? If we used a string like "fn", it could collide with an existing property on the context object. A Symbol() is guaranteed unique.
Step 2 — myApply: Arguments as an Array
apply is identical to call, except it takes arguments as an array (or array-like):
Loading editor...
Step 3 — myBind: Return a New Function
bind is different — it doesn't invoke the function. It returns a new function with this permanently bound.
The key behaviors:
- Returns a new function
- Supports partial application — arguments passed to
bindare prepended - The bound function can be called with more arguments
- A bound function cannot be re-bound
Loading editor...
Step 4 — Edge Cases
The interviewer will now say: "What about primitive contexts? What about calling the bound function with new?"
Primitive context values
When the context is a primitive (string, number, boolean), it should be wrapped in its object equivalent:
Loading editor...
Bound function called with new
This is the tricky one. When a bound function is used as a constructor with new, the this binding should be ignored — the new keyword creates its own this. The native bind handles this:
Loading editor...
Step 5 — Full Solution
Loading editor...
What Interviewers Are Testing
- Implicit binding mechanic — you understand the temp-property trick at the heart of
call/apply Symbolusage — you know to use a unique key to avoid property collisions- Primitive handling — you know primitives passed as context must be boxed with
Object() bind+newinteraction — you understand thatnewoverrides the boundthis- Prototype preservation — you know to wire up
boundFn.prototypesoinstanceofworks
Complexity
| Time | Space | |
|---|---|---|
myCall | O(1) | O(1) |
myApply | O(1) | O(1) |
myBind | O(1) — returns immediately | O(1) — closure captures reference |
Interview Tips
- Start with
callfirst — once you explain the temp-property trick,applyis trivial (just spread the array). This shows you see the pattern. - Mention
Symbolunprompted — saying "I'll use a Symbol to avoid property name collisions" shows you think about defensive coding. - Don't forget the return value —
callandapplymust return whatever the function returns. Many candidates leave this out. - For
bind+new, state "this gets complicated with thenewkeyword" — even if you don't fully implement it, an interviewer will give you credit for knowing the edge case exists.