DEV Community

Rachel Ralston
Rachel Ralston

Posted on

The ‘this' keyword in Javascript

The keyword this in Javascript can be a little slippery to wrap your had around at first.

TL;DR When you refer to this in the global context, it refers to the global variable (which is Window in browsers). When you create a new object with this refers to the object's scope.

What Does this Do?

When you call this on the root of a document, it refers to the document's root object, in the case of our browser this refers to Window.

this keyword

So if we create a function and add a variable to the global scope then we can call it using this

function example

At first hello() returns undefined because saySomething is undefined on window, but once saySomething is defined we get a proper greeting.

So what do we do if we want this to refer to something other than the global scope?

Our first approach is to use call or apply to specify the scope.

code example

This in Objects

Now let's try this in a different way. Let's see what happens when we use this in a function that's been set as the property of an object. In this case, this will refer to the local scope of the adventure object.

code example

In the above case we created the example in an object literal, but what happens when we wrap the example in a constructor function? When we instantiate it with the new keyword, an empty object is created and this will refer to that context.

code example

You can instantiate multiple versions of our Adventure class and this will refer to the local scope of each instance.

code example

Getting Tricky with 'this'

It's been simple enough to follow the context of ‘this' up to this point, but here's where it can start to get tricky. Take the following example:

function Adventure() {
  console.log("Your this is: ", this)
  this.hasAdventure = false
  this.waterslide = function(numGoSlide) {
    if(numGoSlide > 0) {
    this.hasAdventure = true
    celebrate()
    }
  }
}
function celebrate() { 
  console.log("Your this is: ", this)
  if(this.hasAdventure) {
    alert("Yay, you've been on a soggy and thrilling adventure!")
  }
}
Enter fullscreen mode Exit fullscreen mode

You might assume that we'd get the alert here, but when run we don't get much of anything. The reason is that celebrate() was defined on the global scope and so its this refers to the global scope. We can see that when we run this in the console, we're referring to the global scope, global scope doesn't have the attribute hasAdventure, so we don't get the alert.

code example

To fix this conundrum, we can pass Adventure's local this into celebrate and modify celebrate to take an argument. When we update celebrate to take an argument you can't use the reserved word this, so pick another variable to hold that place.

function Adventure() {
  console.log("Your this is: ", this)
  this.hasAdventure = false
  this.waterslide = function(numGoSlide) {
    if(numGoSlide > 0) {
    this.hasAdventure = true
    celebrate(this)
    }
  }
}
function celebrate(you) { 
  if(you.hasAdventure) {
    alert("Yay, you've been on a soggy and thrilling adventure!")
  }
}
Enter fullscreen mode Exit fullscreen mode

Now when we call the function we get the alert!

yay

In conclusion, this is a powerful tool that helps developers easily refer to properties within specific contexts, but can get tricky when passing through different levels of scope.

Good Luck & Godspeed.

Top comments (8)

Collapse
 
madarauchiha profile image
Madara Uchiha • Edited

You didn't really touch the tricky parts of this. Like for example, what happens when you try to pass around a function that refers to this:

const o = {
  f: function() { console.log(this); }
};

o.f(); // prints o, no problems!

const g = o.f; // passed around the function instance, this could be passing to an event handler or some thing

g(); // prints window, oops. 

The main problem with this isn't that you need to pass it around in a parameter or that you might accidentally define things outside the scope.

The main problem with this is that this is determine when the function is called and how the function is called, in the example here, this changed because I no longer called f() with o behind the dot operator. So it defaults to the global object.

Collapse
 
guid75 profile image
Guid75 • Edited

And then, for a most advanced part, one could talk about arrow functions special rules and the bindfunction.

Collapse
 
wesleylhandy profile image
Wesley Handy

Helpful! I tutor students learning to code and will save 'this' 😉 post and use liberally. Well-done and fun to read!

Collapse
 
thegrumpyscot profile image
The Grumpy Scot

Excellent! Cheers :)

Collapse
 
necmettin profile image
Necmettin Begiter

This doesn't make any sense. The comments have hearts, but the content doesn't. (See what I did there?)

Collapse
 
nonsobiose profile image
Nonso Biose

Nice one Rachel. Just incase anyone is also curious about the "This" keyword in java,

why not check the link...... medium.com/java-for-absolute-dummi...

Collapse
 
eoinmurphy profile image
Eoin Murphy

Thanks! Your article actually cleared this topic right up for me.

Collapse
 
vouzamo profile image
John Askew

The most important thing to understand about this is that it refers to the caller from the call stack. Not to be confused with lexical scope.