Creating Bound Functions with Function#bind

Originally published in the A Drip of JavaScript newsletter.

Continuing from some of our previous discussions of functions as first-class values, it's time to tackle Function's bind method. As you might guess, the purpose of bind is to "bind" a function. But what does that mean, exactly?

var hero = {
    name: "Batman",
    signal: function () {
        console.log(this.name + " has been signaled.");
    }
};

// Outputs: "Batman has been signaled."
hero.signal();

Consider if we wanted to let another object signal Batman. We could do something like this:

var commissioner = {
    name: "Jim Gordon",
    signalBatman: function() {
        hero.signal();
    }
};

// Outputs: "Batman has been signaled."
commissioner.signalBatman();

But what if the hero variable gets redefined?

hero = {
    name: "Superman",
    signal: function () {
        console.log(this.name + " has been signaled.");
    }
};

// Outputs: "Superman has been signaled."
commissioner.signalBatman();

Commissioner Gordon is signaling Superman? That can't be right. Let's try using bind instead.

var hero = {
    name: "Batman",
    signal: function () {
        console.log(this.name + " has been signaled.");
    }
};

var commissioner = {
    name: "Jim Gordon",
    signalBatman: hero.signal.bind(hero)
};

hero = {
    name: "Superman",
    signal: function () {
        console.log(this.name + " has been signaled.");
    }
};

// Outputs: "Batman has been signaled."
commissioner.signalBatman();

As you can see, the bind method allows us to create a new function which is permanently bound to a given value of this. You can't even override its this value using call or apply. This can be quite handy when you need to pass around a function that needs a certain this value in order to function correctly.

For instance, consider good old console.log:

// Outputs: "logging"
console.log("console.logging");

var justLog = console.log;

// TypeError: Illegal invocation
justLog("just logging");

It turns out that log just won't work without console. But is there a way we can just pass around the function instead of the entire console object? With bind there is.

// Outputs: "logging"
console.log("console.logging");

var justLog = console.log.bind(console);

// Outputs: "just logging"
justLog("just logging");

Unfortunately, bind is only supported in Internet Explore 9 or higher. If you need this functionality in older browsers, you can use Underscore, Lo-Dash, or the ES5 shim library.

That's a brief introduction to creating bound functions with bind. Next time we'll look at using bind for partial application.

Thanks for reading!

Joshua Clanton

Want to improve your JavaScript skills?
Subscribe to A Drip of JavaScript for biweekly tips to help you level up as a JS developer.