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 isWindow
in browsers). When you create anew
object withthis
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
.

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

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.

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.

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.

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

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!")
}
}
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.

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!")
}
}
Now when we call the function we get the alert!

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.