Skip to main content

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

  • bind creates a new function whose this is fixed forever.
  • The original function is not modified: bind returns 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 this cannot be overridden through call or apply.
  • One exception: a call through new ignores the bound context.

Quick example

javascript
function greet() { console.log(`Hello, I am ${this.name}`); } const user = { name: 'Maria' }; const sayHi = greet.bind(user); sayHi(); // Hello, I am Maria

Here sayHi is a new function whose this is permanently bound to user.

Syntax and what bind returns

javascript
func.bind(thisArg, arg1, arg2, ...)
  • thisArg is the value that becomes this inside 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 this context;
  • 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:

javascript
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:

javascript
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 developer

Here 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:

javascript
function multiply(a, b) { return a * b; } const double = multiply.bind(null, 2); console.log(double(5)); // 10

bind created a new function where a = 2 is fixed, and it only waits for the second argument b.

Difference from call and apply

MethodWhat it doesWhen it runsHow arguments are passed
callCalls the function with the given thisImmediatelyComma separated
applyThe same, but arguments as an arrayImmediatelyAs an array
bindReturns a new function with a bound thisLaterComma separated

Details of bind and the behaviour with new

  1. bind does not modify the original function, it returns a new copy.
  2. The bound this can no longer be changed, not even through call or apply.
  3. If a bound function is called as a constructor (new), the this inside it will be a new object, not the bound context.
javascript
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 new

In other words, bind has a quirk under new: the constructor takes priority over the bound this.

Summary:

PropertyDescription
What it doesBinds the this context and/or part of the arguments
What it returnsA new function
When it runsLater (manually)
Can the context be changed afterwardsNo
Partial applicationYes
Commonly used forCallbacks, event handlers, React components

Common mistakes

  • Expecting bind to 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. After bind the context is fixed, and bound.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 this of their own, so bind has no effect on them.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.