Understanding This keyword with JavaScript Invocation Patterns

The this keyword  is very important in Javascript, and anyone who has worked on any Object Oriented programming language would have surely used ‘this‘.

A good understanding of this is essential and the value of this is determined by how the invocation is done. In this blog, we will go through the various invocation patterns used in JavaScript and how this behaves in each of these patterns. Also, we will learn what’s that, that we sometimes see in our code.

Invocation Patterns

There are four Invocation patterns in JavaScript.

  • The method invocation pattern
  • The function invocation pattern
  • The constructor invocation pattern
  • The apply invocation pattern

Let’s go through each one of them to understand the role and usage of this keyword.

The method invocation pattern

JavaScript objects are a collection of named values, called properties. Object properties can be both primitive values, other objects, and functions.

An object property containing a function definition is called a method. When a method is invoked, this is bound to the object to which the method belongs.

The “this” keyword is used to access methods and properties of the object that invokes the function.

Let’s understand with an example:

 
var myShoppingList = {
 items: [],
 addItem: function (pick) {
    this.items.push(pick);
}
};
myShoppingList.addItem('Cup' );
document.writeln(myShoppingList.items); 
document.writeln('   '); 
myShoppingList.addItem('Cricket Bat');
document.writeln(myShoppingList.items);
}

In the above code, the myShoppingList object is bound to “this” in  the method invocation.

Notes

The same applies to DOM objects. In below code, ‘this’ applies to the object which invokes the method, i.e. $(this) refers to the value of the button ($(“button”)) object​ since the button object has invoked the click () method. :

$(“button”).click(function(event){
     console.log($(this).prop(“name”));
});

 

The function invocation pattern

This invocation pattern refers to normal standalone functions which are not associated with any object.  In such functions, this is bound to the global object, (i.e. window object). Therefore, when we use this in a global standalone function, it refers to the global window object that is the main container of the entire JavaScript application.

A variation in the JS language arises when this is used within a closure – a function within a function.  The inner functions cannot access the outer function’s this variable by directly using the this keyword.

The workaround for this scenario is to assign this to a variable in the outer function and then use the variable within the closure. The variable defined here is often named as that by convention, but it can be named anything you like.  So That is really nothing special in JavaScript but just a name used for this special variable.

Try out the below example to see this and that(named as myVariable in my example) in action and how their values gets bound.

var myShoppingList = {
totalprice : 100
};
myShoppingList.convert = function ( ) {
//myVariable will be used to access this, can be named as that.
var myVariable= this; 
var innerfunction= function ( ) {
myVariable.totalprice =myVariable.totalprice * 65;
};
innerfunction( ); // Invoke innerfunction as a function.
};
myShoppingList.convert();
document.writeln(myShoppingList.totalprice);
document.writeln(this);//[object Window]
//standalone function
var rconv = function(n){
return n/65;
}
document.writeln(this.rconv(myShoppingList.totalprice));
document.writeln(rconv(myShoppingList.totalprice));

What do you think will be the difference in the last two document.writeln statements? Try it out!

Notes:

An exception to this rule is when we use the strict mode, in which case, this holds the value of undefined in global standalone functions.

Now that you have understood the behaviour of this in the two most commonly used invocation patterns, we will look into the other two patterns which are not so straightforward.

The constructor invocation pattern

First lets understand what is a constructor.

Functions that are intended to be used with the new prefix are called constructors.

In classical object orientation, an object is an instantiation of a class. If you have worked on C++ or Java, you would have done this instantiation using the new operator. The new operator instantiates a class and invokes the object constructor. The constructor is the special method having the same name as the object, which initialises the object and makes it ready for use.

The constructor invocation pattern in JavaScript has borrowed this concept from OOP. JavaScript uses objects and functions to implement Object Oriented behavior. In JavaScript, the object is first defined along with associated functions.

By using new operator, new instances of the object are created as we can see in below example. In such scenario, this refers to the current instance of the object for which the function is invoked.

  var List= function (string) {
this.item = string;
};
List.prototype.get_item = function ( ) {
return this.item;
};
var myList = new List("IPhone");// Makes a new instance of List.
var myList2 = new List("IPad"); // a new instance created again
document.writeln(myList.get_item( ));
document.writeln(myList2.get_item( ));

This style of Object constructor functions is not recommended to be used as this is infamous to have caused issues difficult to detect. If you forget to include the new prefix when calling a constructor function, then this will not be bound to a new object, instead bound to the global object resulting in unwanted surprises without any warnings. Using Object.create method is the recommended way to create new objects. 

The apply invocation pattern

The apply invocation pattern is different from the other three patterns, as here we can change or set the context of this explicitly.

So this pattern becomes a little confusing to understand.

This pattern provides the flexibility to set the value of this through the parameters passed to the apply method.

The apply method provides two capabilities through its two parameters:

  1. The first parameter is the value to which we want to bind this to.
    • If null or undefined is passed as the first parameter, this remains bound to the global context.
  2. The second parameter is an array of parameters to be passed to the method.
    • This allows the flexibility to build an array of arguments to be used to invoke a function.
    • This becomes very useful for variadic functions, functions which accept variable number of arguments.

Let’s see an example to understand how we can use the apply method.

  var myShoppingList = {
    price :[],
    totalprice : 100
};
   function sumPrice() {
  var result = 0;
  for (var i = 0; i 
    result += arguments[i];
  }
  return result;
}
  document.writeln(myShoppingList.totalprice);
  document.writeln('
');
  myShoppingList.price = [10,20,30];//build an array of parameters
myShoppingList.totalprice= sumPrice.apply(null, myShoppingList.price); //apply used to calculate total price 
document.writeln(myShoppingList.totalprice);
document.writeln('
');

 function sumPricethis() {
  var result = 0;
  for (var i = 0; i 
    result += arguments[i];
  }
  this.totalprice= result;
}
myShoppingList.price = [50,60,70];//build an array of parameters
sumPricethis.apply(myShoppingList, myShoppingList.price); //this explicitly set using the first parameter of apply
document.writeln(myShoppingList.totalprice);

In the above example, the function sumPrice is called through apply method with a variable parameter array to calculate the totalprice. Here the first parameter is null implying this  remains bound to global context. .

The sumPricethis function shows the variation how the same can be achieved by explicitly setting this to myShoppingList in the first parameter of the apply method invocation.

Notes:

Two other methods which allow to specify the value of this, similar to Apply are Call and Bind.

CONCLUSION

Through this blog, I have explained the different invocation patterns in JavaScript and how the value of ‘this’ is derived in each of these.

Hope now you have a complete understanding of the various Invocation methods and how this takes up different values in different scenarios and you can make use of the power of this in JavaScript, to your advantage.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s