Skip to main content

JavaScript Tutorial — all about “this” keyword with Examples

This keyword in Javascript is an important concept that makes a lot of confusion for beginners and more advanced developers as well. It’s very powerful, but it’s not so easy to use if you don’t know how it works.

In the article, I’m going to explain what is this keyword and what is its value in different cases, with code examples to make it even more apparent.

What is this?

Let’s first explain how Javascript code works to have a better understanding of what this keyword is. Every time we run Javascript in a browser, the engine executes a series of steps, and one of them is a creation of execution context. The execution context may be understood as an environment in which the Javascript code is running. Every execution context references the object, and this object usually refers to this keyword value. In other words, we may say that this keyword is a reference to the object, which called the function. The value of this keyword depends on where it is used.

this used alone

If this will be used alone, not in the context of any object or function, it will refer to the global scope. In the case of the browser, the global object name is a window. Let’s take a look on a simple code example:

<script>
var fruit = "apple";
function getFruit() {
   var fruit = "banana";
   console.log("fruit", fruit); // „banana”
   console.log("this.fruit", this.fruit); // „apple”
}
returnFruit();
</script>

Let’s go through the example above to get more understanding of this keyword used alone. The getFruit() function was called in the global scope, and the first fruit variable is placed in the global scope as well. If you will console.log(this), the window object will have getFruit() method and fruit property.

At this point, when we are calling this.fruit, it will return “apple”, but the local variable fruit will return “banana”.

Our this here is window object so this.fruit refers to global fruit property.

It’s good to mention that in case of strict mode enabled, this in global scope is undefined.

this used with a method

In case of creating a new object from a constructor, then our this keyword refers to the new instance of the object.

Let’s take a look at the example:

var firstName = "Peter";
var lastName = "Strong";

function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.returnName = function() {
    return this.firstName + ' ' + this.lastName;
  };
}

let newPerson = new Person("Kate", "Smith");
console.log(newPerson.returnName()); // "Kate Smith"

In the case of calling returnName() method, it will refer to the newPerson object, which was created using Person constructor, and our value will be „Kate Smith”, not „Peter Strong” because we are using newPerson object properties.

this used in a function

this keyword used inside a function can be a little tricky. It’s good to remember that function in Javascript is an object. It has its own properties, one of them is this and value its value depends on how it’s invoked. If the function is invoked by any object, then this value is the object. Otherwise, our function of this property is a global object – window. Let’s take a look at a code example.

var catName = "Garfield";
var catColor = "orange";

function getCat() {
  return this.catName + ' is ' + this.catColor;
}

var cat = {
  catName = "Jerry",
  catColor = "gray",
  getCat: function() {
    return this.catName + ' is ' + this.catColor;
  }
}

console.log('Cat in gloabl scope', getCat()); // "Garfield is orage"
console.log('Cat in object scope', cat.getCat()); // "Jerry is gray"

If we analyze the code, we can see two functions, one of them is a global scope function, and one of them is a cat object method. While we are calling the global scope function getCat(), it uses global scope variables, because this keyword in the function refers to the global object. In the case of the getCat() method of cat object, this refers to cat object properties, and this is how we get 2 different results from such similar functions.

this used in event

In case of events, after triggering any event, we call the event handler. These handlers are a function that is invoking some code. While we use this keyword in the event handler, this refers to the HTML element, which started the function. It’s good to remember that the DOM model is a tree of objects, so each HTML element on the page is stored as an object inside it. Let’s take a look at some example code:

<button onclick="this.style.backgroundColor='blue'">Click here!</button>

Now we can see that using this, we can refer to the button HTML object and manipulate its styles, for example.

*call(), apply() and bind() *

There are three methods in Javascript which help us to set this value, it’s call(), apply() and bind().

Sometimes it happens that we want to borrow a method from the object and use it with the other context than the error will appear. Let’s take a look at the code:

var boy = {
  greeting = 'Hello',
  sayHi: function() {
    return this.greeting;
  }
}

var spanishBoy = {
  greeting: 'Hola'
} 

boy.sayHi(); // "Hello";

What can we do if we would like to use sayHi() function but with a spanishBoy variable greeting? Here is where call(), apply() and bind() are handy. Let’s go through all of them and check what differences are.

call()

call() method allows us to assign this keyword new value. We can pass multiple arguments to call() method. The first argument is the value of new this, and next, we can pass function parameters. As a result, the function with new this and passed arguments is invoked. Let’s take a look a the code:



var boy = {
  greeting = 'Hello',
  sayHi: function() {
    return this.greeting;
  }
}

var spanishBoy = {
  greeting: 'Hola'
} 

boy.sayHi(); // "Hello";

boy.sayHi.call(spanishBoy); // "Hola";

Here you can see the result of using the call() method. The sayHi() method was invoked immediately with the spanishBoy context, and we had a possibility to use the boy object method without creating a new method for spanishBoy object.

apply

Let’s take a look at the next method, apply(). This method is very similar to call(), it also lets us change this value and invokes function immediately after it is used, but there is a small difference between them. While passing arguments to call() method, it looked like this: call(newThis, arg1, arg2, arg3). In case of an apply() function instead of passing each argument separately, we can pass them as an array, like this: apply(newThis, [arg1, arg2, arg3]).

bind

bind() method differs from call() and apply() a little. Instead of calling the function immediately, bind() creates and returns a new function with new this value assigned. Let’s take a look at the code example.

var boy = {
  greeting = 'Hello',
  sayHi: function() {
    return this.greeting;
  }
}

var spanishBoy = {
  greeting: 'Hola'
} 

boy.sayHi(); // "Hello";
const sayHola = boy.sayHi.bind(spanishBoy);
sayHola(); // "Hola";

In this example, we can see that we were able to create a new function called sayHola(), and you can invoke it anytime.
Using bind() method may be very useful while dealing with asynchronous code or if you want to pass just a some of the parameters to your function.

Conclusion

In this article, I went through the definition and usage of this keyword in Javascript. I explained, what kind of this value you can expect in different scenarios, and described 3 important methods: call(), apply() and bind().

Take into consideration how important it is to understand this keyword to use it correctly and avoid lots of errors in your code, I hope you will find this article useful. Also, it’s good to remember that understanding basics of Javascript will be very helpful in mastering more advanced concepts.

Have a nice coding!

Comments

Popular posts from this blog

Understand Angular’s forRoot and forChild

  forRoot   /   forChild   is a pattern for singleton services that most of us know from routing. Routing is actually the main use case for it and as it is not commonly used outside of it, I wouldn’t be surprised if most Angular developers haven’t given it a second thought. However, as the official Angular documentation puts it: “Understanding how  forRoot()  works to make sure a service is a singleton will inform your development at a deeper level.” So let’s go. Providers & Injectors Angular comes with a dependency injection (DI) mechanism. When a component depends on a service, you don’t manually create an instance of the service. You  inject  the service and the dependency injection system takes care of providing an instance. import { Component, OnInit } from '@angular/core'; import { TestService } from 'src/app/services/test.service'; @Component({ selector: 'app-test', templateUrl: './test.component.html', styleUrls: ['./test.compon...

How to use Ngx-Charts in Angular ?

Charts helps us to visualize large amount of data in an easy to understand and interactive way. This helps businesses to grow more by taking important decisions from the data. For example, e-commerce can have charts or reports for product sales, with various categories like product type, year, etc. In angular, we have various charting libraries to create charts.  Ngx-charts  is one of them. Check out the list of  best angular chart libraries .  In this article, we will see data visualization with ngx-charts and how to use ngx-charts in angular application ? We will see, How to install ngx-charts in angular ? Create a vertical bar chart Create a pie chart, advanced pie chart and pie chart grid Introduction ngx-charts  is an open-source and declarative charting framework for angular2+. It is maintained by  Swimlane . It is using Angular to render and animate the SVG elements with all of its binding and speed goodness and uses d3 for the excellent math functio...

How to solve Puppeteer TimeoutError: Navigation timeout of 30000 ms exceeded

During the automation of multiple tasks on my job and personal projects, i decided to move on  Puppeteer  instead of the old school PhantomJS. One of the most usual problems with pages that contain a lot of content, because of the ads, images etc. is the load time, an exception is thrown (specifically the TimeoutError) after a page takes more than 30000ms (30 seconds) to load totally. To solve this problem, you will have 2 options, either to increase this timeout in the configuration or remove it at all. Personally, i prefer to remove the limit as i know that the pages that i work with will end up loading someday. In this article, i'll explain you briefly 2 ways to bypass this limitation. A. Globally on the tab The option that i prefer, as i browse multiple pages in the same tab, is to remove the timeout limit on the tab that i use to browse. For example, to remove the limit you should add: await page . setDefaultNavigationTimeout ( 0 ) ;  COPY SNIPPET The setDefaultNav...