call, apply and bind in depth — and how to write bind yourself
call and apply run a function now with a chosen this; bind returns a new function. Learn partial application, why bound functions stay bound, and new on them.
Comes up in: JavaScript, Coding
Learn#
In an interview, Kunal is asked to write bind. He writes return () => fn.call(thisArg) and is asked three follow-ups he cannot answer: what about arguments, binding twice, and new?
All three methods choose this. fn.call(thisArg, a, b) and fn.apply(thisArg, [a, b]) run fn now; they differ only in how arguments are passed. fn.bind(thisArg, a) runs nothing. It returns a bound function with this fixed.
Arguments given to bind are fixed too, in front of later ones. That is partial application.
A bound function’s this cannot be changed again, not even by another bind.
call also lets you use one object’s method on another — method borrowing.
function intro(greeting, punct) { return `${greeting}, I am ${this.name}${punct}`; }
const asha = { name: "Asha" };
console.log(intro.call(asha, "Hi", "!"));
console.log(intro.apply(asha, ["Hello", "."]));
const hey = intro.bind(asha, "Hey");
console.log(hey("?"));
console.log(hey.bind({ name: "Ravi" })("!"));
console.log(Array.prototype.slice.call({ 0: "a", 1: "b", length: 2 }));Output (verified)
Hi, I am Asha! Hello, I am Asha. Hey, I am Asha? Hey, I am Asha! [ 'a', 'b' ]
bound function
- target: intro
- this: asha
- preset args: ['Hey']
Console
empty
intro.bind(asha, 'Hey') does not run intro. It returns a new bound function.
Read the steps as text
- intro.bind(asha, 'Hey') does not run intro. It returns a new bound function.
- Calling it with '?' runs intro with this = asha and arguments ['Hey', '?'].
- Binding again creates a wrapper around the wrapper. The inner this = asha still wins.
Predict#
Predict first
const f = intro.bind(asha); f.call({ name: 'Mei' }, 'Yo', '!') — what is returned?
call can pass arguments to a bound function, but it cannot change its this — the bound value wins. Only new overrides it.
Interview angle#
Say it like this — about 30 seconds
“
callandapplyinvoke a function immediately with a chosenthis;calltakes arguments one by one,applytakes an array.bindreturns a new function withthisand optionally leading arguments fixed — partial application. A boundthiscannot be changed by latercallorbind, butnewignores it and creates a normal instance. To implementbind, I return a function that merges preset and new arguments, usesapply, and checksnew.targetfor the constructor case.”
Follow-up Implement Function.prototype.bind.
fn.apply(thisArg, [...preset, ...args]); when called with new (new.target is set), returns new fn(...preset, ...args).Follow-up When would you use apply today?
Math.max(...nums). It still appears in wrappers that forward this and arguments.Follow-up What is method borrowing?
Array.prototype.slice.call(arrayLike). Array.from now covers that case.Practice#
Timed, like the real round
Write myBind(fn, thisArg, ...preset) in 20 minutes, as a standalone function (the prototype version is in JS.15.01).
Done when
thisis fixed, and preset arguments come before call-time arguments.- Binding the result again does not change
this. newon the result makes an instance offn, ignoring the boundthis.
Remember#
Try to answer each card before you open it. Then add them to your reviews.
How do call and apply differ?
call takes arguments one by one; apply takes them as an array.
What does bind return?
A new function with this (and any preset arguments) fixed; it does not call the original.
Can a second bind change a bound function's this?
No. The first bound this wins.
What happens with new on a bound function?
The bound this is ignored; a new instance of the original function is created.
Go deeper
Four layers. Stop at the one your interview needs; each ends with a quick check.
The core ideaEvery round
call/apply: run now, choose this. bind: run later, this and leading arguments fixed forever (except for new).
Check yourself: Which of call, apply and bind does not run the function?
bind.
How it works underneathSenior rounds
A bound function is an exotic object with [[BoundTargetFunction]], [[BoundThis]] and [[BoundArguments]]. Calling it calls the target with those values Source: ECMA-262: Bound function exotic objects. Its name is “bound ” plus the target’s name.
Check yourself: Which internal slots does a bound function have?
[[BoundTargetFunction]], [[BoundThis]] and [[BoundArguments]].
Edge cases and trapsWhere people slip
With new, the bound this is dropped, but preset arguments still apply:
function Point(x, y) { this.x = x; this.y = y; }
const AtX1 = Point.bind({ ignored: true }, 1);
const p = new AtX1(2);
console.log(p.x, p.y, p instanceof Point, "ignored" in p);Output (verified)
1 2 true false
Check yourself: Is an object made with new on a bound Point an instance of Point?
Yes.
In productionStaff-level answers
Each bind creates a new function, so binding in a render or a loop breaks equality checks such as React.memo Source: MDN: Function.prototype.bind(). Bind once (constructor or field) or use stable callbacks. For partial application of pure functions, a small arrow is often clearer than bind(null, …).
Check yourself: Why can bind inside render cause extra re-renders?
It creates a new function each time, so props compare as changed.
Finished the five steps? Mark it, and its cards join your reviews.
Last checked 2026-10-31. Spot a mistake? Use “Report an error” below — fixes are listed on the corrections page.
Interview questions this answers
- Implement
Function.prototype.bind.