Check out myAngular article series with live demos and Facebook group Angular - Advanced Topics

JavaScript and bind

Torgeir "Tor" Helgevold
- JavaScript Developer and Blogger
Published: Sun May 03 2015

One confusing thing about JavaScript is how the meaning of 'this' changes based on execution context. In this post I will demonstrate how to use bind() to inject the meaning of 'this' in functions where it's referenced directly.

Throughout the post I will be using the following example

function print(){ console.log('Quarterly Results'); for(var i = 0; i < this.inventory.length; i++){ console.log(this.inventory[i]); } console.log('Commission'); console.log(this.commission); } function calculateCommission(commission){ this.commission += commission; }

print() creates a simple report and calculateCommission() accumulates someone's commission.

Common to both functions is the assumption that 'this' refers to an object with certain properties. At first glance this restriction may seem to severely limit the flexibility of these functions. The fact that the properties, commission and inventory, are hardwired into the functions may seem like a bad idea, but it turns out that using bind() lets us inject and control the meaning of 'this' to make it more flexible.

In the following code sample I will demonstrate how we can reuse both functions for both a computer store and a car store.

var CarStore = function(){ this.inventory = ['Volvo','Mazda','Chevy','Ford']; this.commission = 0; }; var ComputerStore = function(){ this.inventory = ['Pc','Mac','Monitor']; this.commission = 0; }; var carStore = new CarStore(); var carSale = calculateCommission.bind(carStore,100); carSale(); carSale(); var carReport = print.bind(carStore); carReport(); var computerStore = new ComputerStore(); var computerSale = calculateCommission.bind(computerStore); computerSale(10); computerSale(20); var computerReport = print.bind(computerStore); computerReport();

As you can tell from the code above, bind() enables us to pass in an object that controls the meaning of 'this'. As a result the same function can be used to print a report for completely different implementations. The first argument passed defines the meaning of 'this' and any additional arguments serve as regular function arguments.

Not only can we control the meaning of 'this', but we can also pre-set additional input parameters, and pass in others. This concept is often referred to as currying. When calculating the car store commission I am pre-setting all the parameters – including the commission. However, for the computer store I am making the commission an argument per sale.

How does this magic work? Under the covers bind() returns a new function, identical to the original, except it changes the meaning of 'this' based on the first argument.

If you liked this article, share it with your friends on social media:

We also have a new Facebook group about advanced Angular topics.

I invite you to follow me on twitter