When to use .bind() in JS

In a nutshell, .bind() returns a new function that when called will call the original function with a specific this value and (optionally) some new arguments preprended to the argument list.

.bind() is used when you need to pass a callback (e.g. some sort of function reference), but you want the caller to call your function with a specific this value. This is most common when your function is actually a method and you want the this value set to be the a specific object so the method will operate on that specific object . If you don't use .bind() in those cases, then the this value will be determined by the caller (not you) and if the caller doesn't set it specifically, it will end up being the global object or (in strict mode) undefined. If what you were passing was a method that relies on a specific value of this in order to do its job, it would not work properly with the wrong this value.

So, if you want to control the value of this when your callback is called, you can use .bind(). Internally, .bind() just creates a small stub function that just remembers the this value you pass it and calls your function with .apply() to set the this value. .bind() is not magic as it can be done manually too.

.bind() also has the capability to add extra arguments to the function so, if you want to add arguments beyond what the normal caller of the callback uses, you can specify those with .bind() too. It creates a stub function that will add these extra arguments and set the this value.


Let's say you have your Person object and you want to hook a button up to the .say() method for a particular Person object.

<button id="talk">Talk</button>

And, if you tried this javascript:

"use strict";
var bob = new Person("Bob", "Smith");
document.getElementById("talk").addEventListener("click", bob.say);

What you would find is that the say() method is called, but it would be missing two things. It would be missing the right this reference (which would be set to the button object because that's how addEventListener calls its callbacks) and it would be missing the argument that say(message) expects.

So, you could solve this yourself with your own stub function that calls bob.say() with all the right arguments:

"use strict";
var bob = new Person("Bob", "Smith");
document.getElementById("talk").addEventListener("click", function(e) {
    bob.say("Hello");
});

Or, you could use .bind():

"use strict";
var bob = new Person("Bob", "Smith");
document.getElementById("talk").addEventListener("click", bob.say.bind(bob, "Hello"));

There is no magic in .bind(). It can be entirely simulated in javascript. In fact, here's a polyfill for it from MDN:

if (!Function.prototype.bind) {
  Function.prototype.bind = function(oThis) {
    if (typeof this !== 'function') {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }

    var aArgs   = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP    = function() {},
        fBound  = function() {
          return fToBind.apply(this instanceof fNOP && oThis
                 ? this
                 : oThis,
                 aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}

This may look more complicated than it is because of all the error checking, but it's really just return a new function that combines two sets of arguments and then calls the original function with a specific this value.


This is possibly the simplest way to explain it in a practical sense. Since most answers have given a theoretical definition and explanation, I will show a straightforward use case. You would use bind when you want to the function being called to have a different this value than the default one.

var NS = {
  user     : "self",
  getUser  : function() { return this.user; }
};

var CLOSURE = NS.getUser;

// error user is undefined, "this" in that context refers to the global object, "window"
console.log(CLOSURE());

// Bind the function call to NS object
console.log(CLOSURE.bind(NS)());

http://jsfiddle.net/ev3z3td3/2/


Use bind() when you want a function that always runs with a specific this value.

It's useful for more functional programming, when passing around functions as callbacks or event handlers.

var User = function(name) { this.name = name; };
User.prototype.poke = function() { alert "Hey, don't poke " + this.name; };
var bob = User('Bob');

// assume jQuery for brevity, and because it screws with `this` in callbacks
$('#some-element').click(bob.poke.bind(bob));

This will alert "Hey, don't poke Bob" because you passed it a bound function. So if that element, was explicitly about Bob, it makes sense to bind the event handler to him.


But there are other ways to do this without bind, of course.

$('#some-element').click(function() {
  bob.poke();
});

The difference can be a matter of style. And bind didn't use to have lots of support in all browsers, so lots of JS programmers figured out other ways to do it, and lots of those other ways are still in use today.


One clear win is when you want to pass the same function around to many different places, and you want an explicitly set this.

var bobPoke = bob.poke.bind(bob);

onFoo(bobPoke);
onBar(bobPoke);
onBaz(bobPoke);

Tags:

Javascript