JavaScript's function.bind and Why You Should Know it Exists

I was getting really carried away with fancy JavaScript objects while working on a side project recently, and I ran into a difficult problem. I needed an object to produce instances of any given object with any initial parameters. I hit a few obvious dead ends before discovering something I was surprised I hadn't used before: function.bind.

The dead ends

My first thought was to pass an initial object in and create deep copies of it. However, deep copying is not so easy in JavaScript, especially for complicated objects. Trying to do it manually, I ran into the problem where my object contained a cyclical reference. My simple recursive solution wound up in an infinite loop, and avoiding this in all cases looked like more trouble than it was worth.

Admitting defeat and looking towards jQuery, jquery.clone only works for DOM objects, and jquery.extend simply wasn't working for objects created with new that have arguments.

Another somewhat sketchy solution was to have the constructor and all arguments passed in as an array. Then I would call the constructor in my object. function.apply works nicely for spreading an array as a list of arguments. However, it doesn't work with the new keyword! A very well written article from 2ality pointed me in the right direction...

Bind to the rescue

function.bind takes a this argument and a series of arguments and produces a new function with the given this set and and the arguments provided already set. Here's the definition from the MDN article on bind:

fun.bind(thisArg[, arg1[, arg2[, ...]]])

Let's take a look at how you might use this in a simple case. Here we have a function getFullName, and we'll use bind to create a new function getMyName.

var getFullName = function(title, firstName, lastName) {
    return title + " " + firstName + " " + lastName;
};

var getMyName = getFullName.bind(null, "Mr.", "Justin", "McCandless");

console.log(getMyName()); // "Mr. Justin McCandless"

So by using bind, I created a function that calls an original function with a specific set of arguments. This becomes especially useful because it works with objects created with new, like this:

var Dog = (function() {

    Dog.prototype.name = "Noname";
    Dog.prototype.color = "unknown";

    function Dog(name, color) {
        this.name = name;
        this.color = color;
    }

    return Dog;

})();

var rover = new Dog("Rover", "red");

var Rover = Dog.bind(this, "Rover", "red");

var rover2 = new Rover();

Our new object Rover creates a dog with the same arguments as rover. Since this is javascript, you can pass this function wherever you want, or set it as a parameter of another object, and it you will still be able to create a rover object with a simple new Rover().

This saved the day for me, where my original object needed to create other objects. I simply pass in a bound function and invoke it with new whenever I need to create one. This is much easier than I realized was possible, and I imagine see more uses for function.bind now that I realize something so useful exists.