Implement call(), apply() & bind() from Scratch

Implementing call, apply, and bind is one of the most common JS interview questions. Here's how each one borrows this, and how to write polyfills that pass every edge case.

12 min read
JavaScript
Interview
Implementation
this

TABLE OF CONTENTS

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 with this set to thisArg and arguments passed individually.
  • apply(thisArg, argsArray) — same as call, but arguments are passed as an array (or array-like object).
  • bind(thisArg, ...args) — does NOT invoke the function. It returns a new function with this permanently bound to thisArg, 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:

  1. Temporarily attach the function as a property on the context object
  2. Call it as obj[tempKey]() — implicit binding sets this
  3. 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:

  1. Returns a new function
  2. Supports partial application — arguments passed to bind are prepended
  3. The bound function can be called with more arguments
  4. 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
  • Symbol usage — 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 + new interaction — you understand that new overrides the bound this
  • Prototype preservation — you know to wire up boundFn.prototype so instanceof works

Complexity

TimeSpace
myCallO(1)O(1)
myApplyO(1)O(1)
myBindO(1) — returns immediatelyO(1) — closure captures reference

Interview Tips

  • Start with call first — once you explain the temp-property trick, apply is trivial (just spread the array). This shows you see the pattern.
  • Mention Symbol unprompted — saying "I'll use a Symbol to avoid property name collisions" shows you think about defensive coding.
  • Don't forget the return valuecall and apply must return whatever the function returns. Many candidates leave this out.
  • For bind + new, state "this gets complicated with the new keyword" — even if you don't fully implement it, an interviewer will give you credit for knowing the edge case exists.

Related Questions


Let's Connect

© 2026 Naveen Karthik // Built with React & MUI