The call method

Functions in javascript have three very cool methods available to them. They are call, bind and apply.
These useful functions allow us to change what the this keyword refers to in the current execution context. In this post I’ll be looking at the call() method. 

Let’s use a simple car application as an example. Say we have a function just logs the details of a car.

function getCarDetails() {
	console.log('The car you\'re interested in is ' + this.model + ' ' +
				 this.make + '. It has ' + this.mileage + 
				 ' on the clock, and is a ' + this.year + 
				 ' model.');
}

getCarDetails();

If this simple application was run, we’d get the following printed out in the console:

The car you’re interested in is undefined undefined. It has undefined on the clock, and is a undefined model.

Wow, the car seems to be undefined. Not cool. This is because the this keyword is looking at the global object for model, make, mileage, clock and year. And they are unfortunately not defined.

So, to remedy this and to see call() in action, lets add a car object.

function getCarDetails() {
	console.log('The car you\'re interested in is ' + this.model + ' ' +
				 this.make + '. It has ' + this.mileage + 
				 ' on the clock, and is a ' + this.year + 
				 ' model.');
}

var car1 = {
	model: 'Renault',
	make: 'Duster',
	mileage: '16000km',
	year: '2015'
};

getCarDetails.call(car1);

If you run the file now, you’ll should the following in the console – The car you’re interested in is Renault Duster. It has 16000km on the clock, and is a 2015 model. Essentially you’re setting what this should refer to – the car1 object.

This does lend itself to some cool patterns. One of them is the concept of function borrowing.

var carDetails = {
	model: 'Renault',
	make: 'Duster',
	mileage: '16000km',
	year: '2015',
	getDetails: function() {
		console.log('The car you\'re interested in is ' + this.model + ' ' +
				 this.make + '. It has ' + this.mileage + 
				 ' on the clock, and is a ' + this.year + 
				 ' model.');
	}
};

carDetails.getDetails();

var car2 = {
	model: 'Mini',
	make: 'Cooper',
	mileage: '160km',
	year: '2016'
};

carDetails.getDetails.call(car2);

Firstly we create a carDetails object. It has a function which logs the car details. It will log the car model, make, mileage and year as they’ve been defined in the object. If we then create a second car object, we don’t have to create a getDetails function again, we can ‘borrow’ it from the first function. Thats what the following line does.

carDetails.getDetails.call(car2);

Note that getDetails function is not invoked. The call() method is used to bind the function to the second car object.

I think this is pretty cool.

References and further reading:

MDN

You Dont Know JS

Leave a Reply

Your email address will not be published. Required fields are marked *