The JavaScript Bind Function

  • Written

The JavaScript bind function is a common-place utility when working with many different frameworks and libraries. It’s purpose is to bind the this value to a static object and is useful when passing functions around as callbacks, where maintaining the correct this value is required. A common convention to circumvent this utility is the var that = this, but this isn’t very feasible everywhere.

In modern JavaScript implementations the function is built directly onto Function.prototype, giving us bind functionality on every function. For our implementation we’ll be implementing a standalone functionality that works similar to the built-in bind function.

However, it’s important to note that bind also comes with another handy feature. It accepts an unlimited number of arguments after the context to pass in as the function parameters, from left to right.

var slice = Array.prototype.slice;

/**
 * Bind a function to a certain context.
 *
 * @param  {Function} fn
 * @param  {Object}   context
 * @param  {*}        ...
 * @return {Function}
 */
function bind (fn, context /*, ...args */) {
  var args = slice.call(arguments, 2);

  return function () {
    return fn.apply(context, args.concat(slice.call(arguments)));
  };
};

Bind allows us to keep the this context when passing the callback to another function. Imagine passing a function that uses this into setTimeout or someone elses library utility, where this could be unpredictable.

function greet (greeting) {
  return greeting + ' ' + this.user;
};

greet('Hello'); //=> "Hello undefined"

var boundGreet = bind(greet, { user: 'Bob' });

boundGreet('Hello'); //=> "Hello Bob"

We also have another useful feature built into bind - partial application. Partial application is essentially the act of pre-filling function arguments. Any future arguments are then appended to the arguments we have already defined.

function greet (user, greeting) {
  return greeting + ' ' + user;
};

var greetBlake = bind(greet, null, 'Blake');

greetBlake('Hi'); //=> "Hi Blake"
greetBlake('Hello'); //=> "Hello Blake"

Bonus Implementation using Variadic

In my last post, I introduced the concept of a variadic function. As this article demonstrates, bind is a perfect example of a variadic function, so let’s reimplement bind with the variadic function.

var bind = variadic(function (fn, context, args) {
  return variadic(function (called) {
    return fn.apply(context, args.concat(called));
  });
});

Questions? Find me on Twitter, Mastodon or my repo.