11 October 2014

Hi there,

This is the first formal post of my blog, the idea here is to bring relevant topics and discussions that I have faced in my career. Considering that, I decided to pick up a subject that is very confusing even for experienced developers, specially for those who came from an object oriented programming and aren’t so familiar with Javascript. The “this nightmare” can bring on some bugs that are really messy and hard to track. Actually it is some of the basic knowledge of the Javascript language that took me a long time to understand and consequently decided to write about. So, let’s dive into how the this reference works in Javascript.

Different Types of Invocation

The first step to understand how the this reference works in Javascript is know that it depends on how it is being referenced. There are four distinguished ways to do that and they are:

  • As a simple function invocation.
  • As a method invocation.
  • As an object creation.
  • Using the .apply and .call functions.

Let’s see each one and discuss the contrasts between them.

As a Simple Function Invocation

That’s the simplest way to invoke a function, in a direct function call in Javascript the this reference is bound to the global object at runtime. Let’s go for some real life examples:

  • Open a Chrome browser and then open the Developer Tools (F12).
  • Go to Console item in the toolbar.
  • Create a simple function called doSomething as follow.
		function doSomething(){
 console.log( this ); 
}
  • Call the doSomething function.
		doSomething();
  • Note that the this points to the window object.

At this point you should have the same as image below:

My helpful screenshot

As a Method Invocation

For those with a object oriented background, the method invocation is the most natural type of invocation. When a function is a property of an object, that function can be invoked as a method using the object’s instance and in this case the this reference clearly will be bounded to the instance of that object. Here’s an example:

  • Open a Chrome browser and then open the Developer Tools (F12).
  • Go to Console item in the toolbar.
  • Create a Javascript object called simpleObject and add a method simpleMethod as follow.
var simpleObject = 
{ 
 counter: 0, 
 addCounter: function(value){ 
  this.counter += value;
 } 
};
  • Then, call our method addCounter on the instance of simpleObject.
		simpleObject.addCounter(1);
  • Print the value of our variable counter by doing
		simpleObject.counter;

So, you’ll have the following values in your console:

My helpful screenshot

What happened in the example above? We created an object called simpleObject with two attributes: counter and addCounter. An anonymous function that is responsible for add an value to the counter attribute is associated with the addCounter attribute using the this to point to the instance of the object, then we call the method addCounter with “1” as parameter and next check the value of counter attribute. So, in a method invocation inside an Javascript object the this reference points to the instance of the object.

As an Object Creation

AKA referenced as Constructor Invocation, this method considers that any named function can be used as a constructor. There’s no difference in the function declaration, the difference is in how the function is invoked once it uses the new keyword. If a function is invoked with the new prefix a new object is created and this is assigned to that object. Let’s see how it works:

  • Open a Chrome browser and then open the Developer Tools (F12).
  • Go to Console item in the toolbar.
  • Create a Javascript function called Creation (By convention, once it’s a constructor we’ll keep it with a capitalized name). In this function, create an attribute called firstAttribute and bound it to a function associated with this.
function Creation()
{
 this.firstAttribute = function () { return this; };
}
  • Now, create an object using the constructor.
	var objectOne = new Creation();
  • Check the value of firstAttribute inside objectOne.
	objectOne.firstAttribute();

So, the value of this is an empty object created when the function Creation was called with the prefix new as in the following image:

My helpful screenshot

Using the .apply and .call Methods

And last, the .apply and .call are methods that you can set any object you want as this. Since functions are what we call as first class citizens they can have properties and methods, just like an object and .apply and .call are two methods available for all functions in Javascript. First class citizens is one of the most important definitions of Javascript functions and you should read about it if don’t feel confident enough in this subject. So, as said before, .apply and .call are opened for you choose what will be your this reference, let’s practice:

  • Open a Chrome browser and then open the Developer Tools (F12).
  • Go to Console item in the toolbar.
  • Create a function sumArray that sum the values of an array.
function sumArray(){
 var sum = 0;
 for(var n = 0; n < arguments.length; n++){
  sum += arguments[n];
 }
 this.sum = sum;
}
  • Create two variables and name them as object1 and object2.
  • Call the sumArray function using the apply method. As parameter pass the object1 to be the reference of “this” and an array with the values will be used to sum.
	sumArray.apply(object1, [1,2,3]);
  • Call the sumArray function using the call method. As parameter pass the object2 to be the reference of “this” and the values separated with commas to be used to sum.
	sumArray.call(object2, 3, 4, 5);
  • Note that the first parameter will be our this in both cases, the difference between the two methods is that .apply expect an array and .call values separated by a single comma.
  • Inside sumArray function, we setted this.sum value, so let’s check those values. Type object1.sum and object2.sum to see if they were setted right.
	object1.sum;
	object2.sum;

My helpful screenshot

Strict Mode

We mentioned some times that the this reference is bounded to the global object at runtime but, what it means? It depends on the environment you’re executing the code. If you run the example above in the console it will be the window object, if you run inside a NodeJS environment it will be the NodeJS global object. But both environments have (Strict Mode. Strict mode sets the this to an undefined reference. You can see in the link above the advantages of using Strict mode.

For Further Reading

To go deeply in this subject I suggest the following books, both focused in Javascript. The first is a book of You Don’t Know JS Series which I’m currently reading and highly suggest for deeper understanding of the mechanism that this relies on. In the link above you can see that’s there are more interesting topics about JS like Scope, Closures. If you want to buy a copy of the book, click on the link below. The second link is one of the greatest books about JS. Javascript: The Good Parts is an introdutory reference to some of the most important points in JS. Written by Douglas Crockford, creator of JSON.



blog comments powered by Disqus