Function.prototype.bind
Function.prototype.bind returns a new function with a permanently attached this context instead of invoking the function right away. It is the third of the "context control methods" alongside call and apply, and the deferred invocation is exactly what makes it special.
Theory
TL;DR
bindcreates a new function whosethisis fixed forever.- The original function is not modified:
bindreturns a separate copy. - You can fix part of the arguments in advance (partial application).
- The function does not run immediately, it is invoked later by hand.
- The bound
thiscannot be overridden throughcallorapply. - One exception: a call through
newignores the bound context.
Quick example
function greet() {
console.log(`Hello, I am ${this.name}`);
}
const user = { name: 'Maria' };
const sayHi = greet.bind(user);
sayHi(); // Hello, I am MariaHere sayHi is a new function whose this is permanently bound to user.
Syntax and what bind returns
func.bind(thisArg, arg1, arg2, ...)thisArgis the value that becomesthisinside the function when it is called;arg1, arg2, ...are the arguments that will be substituted "by default";- it returns a new function that can be called later.
So bind creates a new function that:
- has a permanently attached
thiscontext; - can have part of its arguments fixed in advance;
- does not execute immediately, but is returned for a later call.
Losing the context in a callback
Most often bind is needed precisely to preserve this when a method is passed as a callback. When the method is passed by reference, its link to the object is lost:
const user = {
name: 'Maria',
sayHi() {
console.log(`Hello, I am ${this.name}`);
}
};
setTimeout(user.sayHi, 1000); // this is lost -> "Hello, I am undefined"
setTimeout(user.sayHi.bind(user), 1000); // correct -> "Hello, I am Maria"The same applies to event handlers and to callbacks in methods such as map, forEach and then.
Partial application of arguments
bind lets you preset not only the context but also part of the arguments:
function introduce(city, job) {
console.log(`I am ${this.name} from ${city}, working as a ${job}`);
}
const person = { name: 'Maria' };
const introduceMaria = introduce.bind(person, 'Kyiv');
introduceMaria('Frontend developer');
// I am Maria from Kyiv, working as a Frontend developerHere the first argument ('Kyiv') is fixed in advance, and the rest are passed at call time.
The context is not always needed, so for pure partial application you pass null:
function multiply(a, b) {
return a * b;
}
const double = multiply.bind(null, 2);
console.log(double(5)); // 10bind created a new function where a = 2 is fixed, and it only waits for the second argument b.
Difference from call and apply
| Method | What it does | When it runs | How arguments are passed |
|---|---|---|---|
| call | Calls the function with the given this | Immediately | Comma separated |
| apply | The same, but arguments as an array | Immediately | As an array |
| bind | Returns a new function with a bound this | Later | Comma separated |
Details of bind and the behaviour with new
binddoes not modify the original function, it returns a new copy.- The bound
thiscan no longer be changed, not even throughcallorapply. - If a bound function is called as a constructor (
new), thethisinside it will be a new object, not the bound context.
function User(name) {
this.name = name;
}
const BoundUser = User.bind({ name: 'Maria' });
const u = new BoundUser('Alice');
console.log(u.name); // Alice, the bound context is ignored under newIn other words, bind has a quirk under new: the constructor takes priority over the bound this.
Summary:
| Property | Description |
|---|---|
| What it does | Binds the this context and/or part of the arguments |
| What it returns | A new function |
| When it runs | Later (manually) |
| Can the context be changed afterwards | No |
| Partial application | Yes |
| Commonly used for | Callbacks, event handlers, React components |
Common mistakes
- Expecting
bindto invoke the function. It only returns a new function; without a pair of parentheses nothing happens. - Not storing the result. A standalone line
user.sayHi.bind(user);is pointless: the original is not modified, the result has to be assigned. - Trying to override the binding with
call. Afterbindthe context is fixed, andbound.call(other)will not change it. - Binding on every render.
onClick={this.handle.bind(this)}creates a new function each time and breaks memoization; bind once or use an arrow function instead. - Binding an arrow function. Arrow functions have no
thisof their own, sobindhas no effect on them.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.