JavaScript: what's the point of bind()?
Tags: javascript, this, bind
Published: 2020-03-25 18:51:04

---
title: JavaScript: what's the point of bind()?
published: true
description: A discussion on the .bind() function found on the Function prototype
tags: JavaScript, this, bind
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/2xg59r17v72yvqfb3wu5.jpg
---

A fellow at work is currently working through a JavaScript course. He shared the following snippet of code:

```javascript
let post = {
    id: 1,
};

let UI = {
    render: function(){
        console.log(this.id);
    }
};

let r = UI.render.bind(post);
r();
```

And asked the question:
>I still don’t fully understand what the point of the bind keyword is and what it is supposed to achieve, maybe you can clarify? Why not just call the object directly with “post.id” instead of “this.id” and then
 binding it in a third function.

Which I thought was a good question -- and I'm sure others have asked it. I'm quite sure I remember asking it myself.

## Functions are first-class citizens

First off, we have to remember that functions in JavaScript are first-class citizens. This means that we can pass them around like any other object:

```javascript
function modifyAndLog(startingNumber, modifyingFunction) {
  const result = modifyingFunction(startingNumber);
  console.log(`Modified ${startingNumber} to get result ${result}`);
  return result;
}

function double(number) {
  return number * 2;
}

function doubleAndLog(number) {
  return modifyAndLog(number, double);
}

doubleAndLog(2); // prints out a message and returns 4
```

See how we can pass functions around like any other object? This is also why the following function declaration syntax works:

```javascript
var add = function(a, b) {
  return a + b;
}
```

(which, of course, is equivalent to the following):
```javascript
var add = (a, b) => a + b;
```

but let's forget about arrow functions (for now) as they introduce a different behavior for `.bind()` (for good reason). I'll circle back to this later. Also, please bear the following in mind with respect to the above syntax:

[1] function variable declarations are hoisted to the top of the file, however the assignment only happens when that code is run:

```javascript
var a = function() {
    b(); // will error
};
a();
var b = function() {
    console.log("b called");
};
```

[2] function variable declarations like the above create anonymous functions, which traditionally gave horrid stack traces when they eventually error: instead of seeing that you have an error in function `a`,you may see just the line number, and an anonymous function specified. Modern browsers and NodeJS versions give better messages, but I still recommend that if you _absolutely must_ use function variable declarations like this, that you do

```javascript
var a = function a() {
    b(); // will error
};
a();
var b = function b() {
    console.log("b called");
};
```

Rather prefer to explicitly define your functions in the form:
```javascript
function a() {
}
```
and "var them off" if you really need to:

```javascript
function a(fn) {
    console.log(fn());
}

function b() {
    return "b called";
}

var bFunction = b; // this var is unnecessary: just here to illustrate
a(bFunction); // prints "b called"
```

## Functions are new, every time

Consider this code:
```javascript
function Foo() {
  this.add = function(a, b) {
    return a + b;
  };
  this.add2 = function(a) {
    return this.add(a, 2)
  };
}

var foo1 = new Foo();
var foo2 = new Foo();

console.log(foo1.add === foo2.add); // logs false
```

This is ye olde syntax for object creation. This, kids, is what we used before the es6 `class` syntax (also used by TypeScript) became available.

Note here that the `Foo` function:
1. Creates a new anonymous function
2. Assigns that to the `doStuff` property on the new'd up object

This is why prototypes exist as they do: in a memory-constrained environment, we don't want code like the above creating many copies of (essentially) the same function. So a better solution to the above would be:

```javascript
function Foo() {
}
Foo.prototype = {
  add: function(a, b) {
    return a + b;
  },
  add2: function(a) {
    return this.add(a, 2);
  }
};

function makeFoo() {
    return new Foo();
}
var foo1 = makeFoo();
var foo2 = makeFoo();
console.log(foo1.doStuff === foo2.doStuff); // logs true
```

In the above, we save memory (and compilation time) by essentially re-using the same function pointer every time we new up a `Foo`. This especially makes a difference if you're newing up hundreds of `Foo`s.

Interestingly, because of the "light-copy" nature of the `prototype`, modifying the prototype later will apply that modification to every instance of the prototype, _even existing ones_:

```javascript
var foo = makeFoo();
Foo.prototype.add = function(a, b) {
    // introduce an off-by-one error
    return a + b + 1;
}
console.log(foo.add(1, 2)); // prints 4, not 3
```

## JavaScript has a history

JavaScript was created by Brendan Eich in a very short time period to embed in Netscape Navigator around 1995. Every time we find something "odd" with JavaScript, bear in mind that:
1. It was created on a shoestring time-budget (about 2 weeks)
2. It had to work on much more constrained machines than today -- even the phone in your pocket is orders of magnitude more powerful, computationally and memory-wise

Prototypes were an elegant solution to the above problem. In essence, the above prototype code could be written as:

```javascript
function makeFoo() {
  var result = {};
  result.add = add.bind(result);
  result.add2 = add2.bind(result);
  return result;
}
function add(a, b) {
  return a + b;
}
function add2(a) {
  return this.add(a, 2);
}
```

The `.bind` calls are necessary so that `add2` has a correct reference for `this` when it is called.

In reality, the mechanism is a little more complex, and involves calls on `this.{whatever}` searching through the prototype chain for methods. But the example above illustrates a possible solution.

_Aside: Also remember that you can set the `this` context for any function by using either `.call` or `.apply`:_

```javascript
function add2(a) {
  return this.add(a, 2);
}
const adder = {
  add: function(a, b) {
    return a + b;
  }
};
const bound = add2.bind(adder);
console.log(bound(2)); // logs 4
console.log(add2.call(adder, 6)); // logs 8
console.log(add2.apply(adder, [10])); // logs 12
```

_The only difference between `.call` and `.apply` is that `.apply` takes an array of arguments, where `.call` takes arguments as parameters. This makes it useful when you want to programmatically build up arguments for a function -- you put them in an array and use `.apply`_

`.bind` can be essentially rewritten as:

```javascript
function bind(ctx, fn) {
    return function() {
        return fn.apply(ctx, arguments);
    };
}
const adder = {
    add: function(a, b) {
        return a + b;
    }
};

function add2(a) {
    return this.add(a, 2);
}
var bound = bind(adder, add2);
console.log(bound(13)); // prints 15
```

## What's `this` anyway?

Every object-oriented programming (OO) language that I've ever encountered has the concept of the current object context within member methods, often called `this`, though VB used `Me` and in Python it can be whatever you like, but the convention is `self`, as it is in Ruby, perhaps a nod to Python which came 5 years earlier? PHP and ITcl use `$this`, which is really just `this` in their own dialect 😆

Consider C#:

```csharp
public class Adder
{
    public int Add2(int a)
    {
        // note that `this` can be dropped in C#,
        // because the compiler can infer that
        // the Add method exists on `this`. But I've
        // included it here for clarity
        return this.Add(a, 2);
    }

    public int Add(int a, int b)
    {
        return a + b;
    }
}
```

Python is more explicit: members must be declared taking in as their first argument the context on which to operate.

```python
class Adder:
  def add(self, a, b):
    return a + b

  def add2(self, a):
    return self.add(a, 2)

foo = Adder()
print(foo.add2(4)) # prints 6
```

It turns out that Python is just being very explicit about what other runtimes and languages do anyway.
For example, if we were to use reflection to invoke `Add2` on the C# class above, it could be:

```csharp
var adder = new Adder();
var add2Method = typeof(Adder).GetMethod(nameof(Adder.Add2));
Console.WriteLine((int)add2Method.Invoke(adder, new object[] { 4 }); // prints 6
```

The .net runtime is doing the same thing when it invokes methods. Similarly, C++ methods are compiled in such a way as to take the context to become `this` as the first parameter, and calls to that method
are compiled to explicitly provide this context. (At least, it was, last I checked).

The concept of `this` is "transparent magic" to the programmer in most OO languages.

## Coming back to answer the original question

There are several circumstances where being able to `bind` is advantageous

### Passing a member as a callback

Imagine this code, which does stuff with DOM elements:

```javascript
class BodyClicked1 {
    _element;
    _clickedCount;

    constructor() {
        this._element = document.querySelector("body");
        this._clickedCount = 0;
        this._element.addEventListener("click", this.clicked.bind(this));
    }

    clicked(ev) {
        this._clickedCount++;
        console.log(`You've clicked me ${this._clickedCount} times`);
    }
}
```

Without the call to `.bind`, the DOM element would call the provided handler (`eventHandler`) without any context, so the line `this._clickedCount++` would error, most likely with an error like `this. is not a function`. The DOM element doesn't have the context, so it can't know what to call. Of course, we could also rewrite the above as:

```javascript
class BodyClicked2 {
    _element;
    _clickedCount;

    constructor() {
        this._element = document.querySelector("body");
        this._clickedCount = 0;
        this._element.addEventListener("click", ev => this.clicked(ev);
    }

    clicked(ev) {
        this._clickedCount++;
        console.log(`You've clicked me ${this._clickedCount} times`);
    }
}
```

But we should also unsubscribe when we're done, which we can't do without a reference to the original subscribing function, ie:


```javascript
class BodyClicked3 {
    _element;
    _clickedCount;
    _clicked;

    constructor() {
        this._element = document.querySelector("body");
        this._clickedCount = 0;
        this._clicked = this.clicked.bind(this);
        this._element.addEventListener("click", this._clicked);
    }

    destroyed() {
        if (this._element) {
            this._element.removeEventListener("click", this._clicked);
            this._element = undefined;
        }
    }

    clicked(ev) {
        this._clickedCount++;
        console.log(`You've clicked me ${this._clickedCount} times`);
    }
}
```

If we didn't have the bound function, a call to `removeEventListener` wouldn't properly unsubscribe, because we'd be passing in a new function:

```javascript
class BodyClicked4 {
    _element;
    _clickedCount;

    constructor() {
        this._element = document.querySelector("body");
        this._clickedCount = 0;
        this._element.addEventListener("click", this.clicked.bind(this));
    }

    destroyed() {
        if (this._element) {
            // doesn't work because it's not the exact same function we bound with
            this._element.removeEventListener("click", this.clicked.bind(this));
            this._element = undefined;
        }
    }

    clicked(ev) {
        this._clickedCount++;
        console.log(`You've clicked me ${this._clickedCount} times`);
    }
}
```

### Frameworks like AngularJS

AngularJS has always been one of my favorite frameworks. Perhaps just because I learned it quite early on, or perhaps because it just did more and sat better with me than Knockout or CanJS did at the time. AngularJS is still kept up to date, so don't count it out. Personally, I find it more flexible than Angular, though both have their merits. Anyway, I'm not here to start The War Of The Angulars 😄 and anything new I write at the moment would probably be in Vue, so there's that 😛

If we have a look at how an AngularJS directive can be created:

```javascript
angular.module("app")
    .directive("CustomElement", ["$scope", function() {
        return {
            restrict: "E",
            template: "<button ng-click='clicked'>Click me</button>",
            controller: function ($scope) {
                $scope.clickCount = 0;
                $scope.clicked = function() {
                    $scope.clickCount++;
                    alert(`you clicked the button ${$scope.clickCount} times!`);
                }
            }
        };
    }]);
```

With the above code, _every time_ a `custom-element` is created, a brand-new `clicked` function is created, compiled and stored in memory. Not a big deal if this is only created a few times in the lifetime of the app, but if you have a bunch of repeated `custom-element` tags, you're paying CPU and memory that you don't have to. We can't use a `prototype` here because AngularJS simply calls the function we gave it with the dependencies we asked for. However, we _can_ use `.bind`:

```javascript
(function() {
    // use a closure to stop the function `clicked` from leaking out or being
    // overwritten elsewhere
    angular.module("app")
        .directive("CustomElement", ["$scope", function() {
            return {
                restrict: "E",
                template: "<button ng-click='clicked'>Click me</button>",
                controller: function ($scope) {
                    $scope.clickCount = 0;
                    $scope.clicked = function() {
                        $scope.clickCount++;
                        alert(`you clicked the button ${$scope.clickCount} times!`);
                    }
                }
            };
        }]);
    function clicked() {
        this.clickCount++;
        alert(`you clicked the button ${this.clickCount} times!`);
    }
})();
```

Whilst `.bind` produces a new function every time, the original function only has to be JIT'ed once -- the bound version is doing something like my example above, performing `clicked.call` with the provided context. In addition, our `controller` function can be kept shorter and neater -- we could even declare the methods in other files, eg if we were using es6 modules or AMD (eg `Require`).

### Binding parameters

`.bind` isn't only useful for binding the context to use for `this` -- you can bind parameters too (essentially, _currying_):

```javascript
function add(a, b) {
  return a + b;
}
var add2 = add.bind(null, 2);
console.log(add2(8)); // prints 10
```

_note that we still need to provide an argument for the context -- above, I didn't really need a context, so I bound `null`_

## Arrow functions

I promised to come back to this...

Arrow functions are not just nice to look at -- they also introduce new behavior with respect to the context of a function.

Consider code like this:

```javascript
class SomeService {
  fetchData() {
    return $.get("/data").then(function(result) {
      return this.process(result);
    });
  }
  process(data) {
    // does some stuff with the data
  }
}
```

I'm sure we were all caught out at some point with code like the above, and `this` not being quite what we expected. A simple solution is:

```javascript
class SomeService {
  fetchData() {
    var self = this;
    return $.get("/data").then(function(result) {
      return self.process(result);
    });
  }
  process(data) {
    // does some stuff with the data
  }
}
```

See that `var self = this;` line at the top? That's an easy go-to as an alternative to using `.bind()`, which we could have, like so:

```javascript
class SomeService {
  fetchData() {
    var bound = this.process.bind(this)
    return $.get("/data").then(function(result) {
      return bound(result);
    });
  }
  process(data) {
    // does some stuff with the data
  }
}
// or, shorter
class SomeService {
  fetchData() {
    return $.get("/data").then(
      this.process.bind(this)
    });
  }
  process(data) {
    // does some stuff with the data
  }
}
```

Both options are unnecessarily cumbersome, so the arrow function was introduced. Arrow functions cannot have their `this` binding changed -- they are assigned `this` from the scope in which they are declared. (They also don't have access to `arguments` or `super`).

Arrow functions make the code above simpler to read and understand:

```javascript
class SomeService {
  fetchData() {
    return $.get("/data").then(
      result => this.process(result)
    );
  }
  process(data) {
    // does some stuff with the data
  }
}
```

When you can use arrow functions, I suggest you do, as they make reading the code a lot simpler for others. When you can't, there's always the trusty `.bind()`

## Wrapping up

`.bind` is an essential tool in the JavaScript developer's toolbox. Understanding how (and when) to use it is vital to being able to write effective JavaScript. Understanding the nuts-and-bolts of `.call` and `.apply` is also good 😄