Tag Archives: Underscore.js

Underscore.js can Bind This!

underscore.js has a really neat method called bind that does something quite interesting. Let me first talk you through what that method is addressing.

One of the foibles in JavaScript is that the this pointer has a somewhat unusual behaviour in that it will point to the window object, when inside a nested function. Take the following example:

var car = {
	engine: 1,
	doorToWheelRatio: function (nrOfDoors){
		
		this.nrOfDoors = nrOfDoors;					
		
		return function (nrWheels) {
			//  'this' refers to window object in here
			return this.nrOfDoors / nrWheels;
		};
	}			
};

There are two instances of this. The second one being in the nested function. That function is not going to behave as expected because the this pointer is pointing to the window object. This is a known foible, especially in light of the fact that the previous this pointer points at the car object.

The historical way in which developers have overcome that is to assign the this pointer to another variable in the enclosing function (e.g. self), thus making it available in the nested function:

var car = {
	engine: 1,
	doorToWheelRatio: function(nrOfDoors) {
		this.nrOfDoors = nrOfDoors;
		var self = this;
		return function(nrWheels) {
		  return self.nrOfDoors / nrWheels;
		};
	}
};

Using underscore.js’ bind function, we can effortlessly bind the this pointer in that nested function to the car object:

var car = {
	engine: 1,
	doorToWheelRatio: function (nrOfDoors){
		this.nrOfDoors = nrOfDoors;

		return _.bind(function (nrWheels) {
			return this.nrOfDoors / nrWheels;
		}, car);
	}			
};

Now both instances of this are pointing at the same object, car.

When I say effortlessly, bear in mind it comes at substantial cost. Take a look at this benchmark which I have performed at perf.com which clearly shows that using bind is an expensive operation compared with using a local variable (as was historically done).

It would be remiss of me not to point out that jQuery also has an equivalent function called proxy. That code would look like the following if we were to use proxy:

var car = {
	engine: 1,
	doorToWheelRatio: function (nrOfDoors){
		
		this.nrOfDoors = nrOfDoors;					
		
		return $.proxy(function (nrWheels) {
			return this.nrOfDoors / nrWheels;
		}, car);
	}			
};

That is all.

Underscore.js Avails Interesting Possibilities with Reduce

Since I began playing around with Underscore.js, I have become obsessed with its reduce method. reduce takes a collection (or an object) and returns a single value. But it is the way in which it does that which makes it compelling. From the documentation, its signature is:

_.reduce(list, iterator, memo, [context])

I’ll start out with a simple example. Probably the kind of example you’ll see everywhere around the Internet:

var result = _.reduce([100, 25, 2], function(memo, num) {
	 return memo / num;
});
// result === 2

The iterator function is being applied to each of the elements of the list. But not only that, it is making available to each iteration the result of the previous iterator-function’s result.

  • In the first iteration, memo has the value 100 and num is 25.
  • In the second iteration, memo has the value 4 and num is 2.

As you can see, the value of memo in the second iteration is equal to the result of the iterator function from the first iteration. So we have this concept of a value which is travelling through the iterations. The parameter memo is short for memoization. This is an implementation detail which is not relevant to this post. As that parameter travels from function to function through the iterations, I am using the name traveller for the purposes of this post.

There are only 2 iterations in this example because the list has 3 items and we have not passed it a seed value as the 3rd possible parameter. If we change that function to the following, we will get 3 iterations and the value of traveller on the 1st iteration will be 10000, whilst the value of num will be 100.

var result = _.reduce([100, 25, 2], function(traveller, num) {
	 return traveller / num;
}, 10000);
// result === 2

When it comes to the iterator function, you are free to be very creative in there. But first, I just want to point out that it is not limited to integers. The following example creates a sentence out of a string array:

var words = ['Reduce', 'is', 'an', 'interesting', 'method'];

var sentence = _.reduce(words, function(traveller, current) {
	var collate = traveller + ' ' + current;
	return collate;
});
//	sentence === 'Reduce is an interesting method'

You can also pass an object as the first parameter. This is where you can do some interesting stuff, like the following example that creates an address object from a person object:

var person = {
	name: 'Dave',
	age: 39,
	address: '28 Scenic Road',
	suburb: 'Kenmore',
	postcode: 4069
};

var address = _.reduce(person, function(traveller, objectValue, objectMember) {
    switch (objectMember) {
		case 'address':
		case 'suburb':
		case 'postcode':
			traveller[objectMember] = objectValue; break;
		default : break;
    }
    return traveller;
}, {});

You can see that I have passed an empty object as the 3rd parameter to reduce, which will be the initial value of the traveller parameter.

Note that I’m not saying the last example is the best way to achieve that end. But that example does show that you can use the reduce function for a great many things beyond simple arithmetic and sentence construction.

Perhaps in a month or 2 I’ll have a really good example that solves a problem nice and elegantly.

Until then!