Check out a free preview of the full Test Your JavaScript Knowledge course

The "this keyword" Lesson is part of the full, Test Your JavaScript Knowledge course featured in this preview video. Here's what you'd learn in this lesson:

Lydia explains the behavior of the "this" keyword in JavaScript. They cover various scenarios, including the global context, regular functions, arrow functions, classes, strict mode, event handlers, and the use of call, bind, and apply methods.


Transcript from the "this keyword" Lesson

>> So the next category is another infamous topic in JavaScript, this Keyword. So, the value of the this Keyword depends on where we use it. In the global context, the value of the this Keyword is the global object, provided that we aren't using useStrict, so not strictMode or inModule.

In a regular function, the value of the this Keyword is the object on which the function is invoked. So here you see that we have object and then logThis, and then first we just invoke logThis on the window object. So in that case, this points to the window.

And the second one, we invoke it on the object or the object. [LAUGH] So in that case, it points to that object because that's the object on which that function was invoked. Then we have Arrow Functions and they don't have their own this value. So the value of this Keyword in an arrow function is determined by the lexical environment in which the arrow function was defined.

So in this case, we have that logThis arrow function which It also logThis, but that error function was defined on the global object, which in browsers is window. So even though we invoke it on the object, that doesn't matter, it didn't matter for regular function, but for arrow function, the value of this is the lexical environment in which the arrow function was defined and not invoked.

So that's just an important difference to remember. Then, we have classes. So if we use this keyword in a constructor function or any methods in a class, then it's the value of the newly created instance. So in this case, we have two instances of user1 and user2 and we invoke getThis on it.

So that this keyword in user1 to getThis points to that instance, you User1 and for user2, it points to the instance user2. And then we have strict mode. So this is just similar to what we just saw. So in that case, if we just invoke it, not on an object, but just kind of standalone, it won't default to that global object that we saw.

So it won't be window, but that in that case it'll be undefined. And the strict mode is also modules. So if you're using ESM, this will be undefined. And event handlers. This keyword is the element that received the events in case you're using a regular function which we are here.

And then we can use either oops, sorry, call, bind, or apply. And that allows us to kind of explicitly tell JavaScript like, hey, this is what this keyword should point to. So with call, it calls that function with a given this value. So in the first one, we say, and make sure that this points to the object that we pass to it.

So it's the object with the username John. Then we have greet.bind, which creates a new function, so it doesn't invoke yet, it just creates a new function objection with a specified this value and also optional initial arguments if you want, but we don't have that here. So again, we have that object with (username: "John" ), and applies pretty much the same as call, but we can actually pass in array instead of just a single object for the arguments.

So in this case, that's text. So text will be, hi there, instead of welcome. All right, so this is different in just like this keyword, there's not one single explanation for it. It really depends on how you're using the this keyword, which is obviously what I'll be creating questions about.

So question 11, what gets logged? So we have a regular function logThis. Then we have an object that contains the logThis property. A logThis two method that returns a logThis invocation, and then a logThis three method that returns the object logThis invocation. So Well this lock object window Object Object Object Object window object object.

[LAUGH] We know that objects are three times window. So just keep in mind we are working with regular functions and there's just one thing that you have to remember in that case. [LAUGH] All right, and the right answer is A, it's object window object. So first we call or we call logThis on object.

And again, it's a regular function, so it depends on the object that calls the function, in this case it's object. Cuz even though it is a property, so we're setting the logThis property on objects. Well we're not calling logThis in that method, it's just a reference to that function.

So we're calling logThis on object, it's a regular function so this points to that object. Then we have logThis2, and we are calling that function on object, but within that function we're just calling it independently. We're not saying like object.logThis, it's just It's just logThis. So in that case, it defaults back to that global, global this, which in this case is window if we are using it in a browser.

And then with logThis3, yeah, we are invoking that logThis3 on object. That doesn't matter, but within logThis3, we are calling logThis on object. So again that this keyword will point to the object on which that method was invoked, so that's object again. Make sense? Perfect, in that case we go to the next question.

I forgot that I had all this which is pretty similar but Question 12, what will the this keyword refer to for each invocation? So we have object8 with a regular foo method and an arrow function bar. Then we have object b with foo that points to object

We're not invoking it, we're just creating a reference to that same function object. We have a bar that's an arrow function, and a regular boz, baz, whatever function that invokes And then what we're logging is,, and objectB.baz, whatever. So yeah, so only objectA, three times objectB, or we'll bar point to Window?

All right, so the right answer here is E, it's object B window object A. So first we're invoking foo on object B, and foo points to a reference to, but again we're not invoking it on the objectB foo method. We're just kind of like creating a reference to the same function object, the same that we just saw, but we're invoking it on objectB, right?

We're creating that lexical environment for objectB. And it's a regular function, so this points to the object that invoked it, doesn't matter where it was Create it, so it's object b. Does it go down? And then we have object, which is an arrow function. So now on bar, we are invoking object, which is also an arrow function.

So it doesn't matter where it is, we don't care about the object that invoked it because it's an arrow function. So it's just about the lexical environment in which it was defined, which in this case case is the window object. And then here we invoke object B, Bas, whatever.

And then that one invokes And that's all we care about. We care about the invocation of foo and that's on the object A, because this is a regular method and that logs at this and we invoked in an object A, so this points to object A. Makes sense?

Any questions? Perfect, yes, you're not done with this yet, because question 13, what gets logged? We again have the regular logThis function. We have obj1, that's going to reference to logThis. We have bar that's an arrow function that invokes it as a regular function. We have bars, we have trucks, [LAUGH] And then we have, then really all we're doing is we're creating a new object2, we're spreading object1.

And then we also add a new foo2 method that is an arrow function that invokes object1 foo, which is that logThis reference to logThis. And that for in loop doesn't matter too much, all we're doing here is we're only invoking the properties in object2. So what would that log would it be only window yeah I'm not gonna say all of them, but just imagine we're invoking all the properties in object2.

Which is pretty much all the properties in object1 plus that foo2 method.
>> Someone in chat just said, my brain hurts. [LAUGH]
>> Yeah, mine too. [LAUGH] All righty, so the right answer is C. It's object2, window, window, object2, and object1. So first, so this is essentially the object2 object that we just created, right?

So we copy the properties from object1 and then we added a foo2 method. This is just how I like to visualize it. Someone calling foo, we're calling logThis, but that's just a reference to the logThis function object. So we're calling it an object2. It's a regular function. So this points to object2.

Then bar is in an arrow function and that doesn't matter because we're invoking it within that arrow function. We're not invoking it on a specific object. And that's all that this cares about is where was this regular function invoked. Nowhere, so it defaults to the global this, so window.

Same for the next method. We're invoking it kind of just stand alone. So it, again, just points to window, global this. And then the next method, we're calling logThis, or we're using logThis, and we're using .call. And as you remember we can use .call to automatically invoke a function with a specified this method.

And, in this case we are calling the regular function Clarks on object2. So in that case we are saying, this refers to this of that of the Coax method. We call that as a regular function on object2. So within that environment, within that lexical environment, this points to object2.

And so that means that if we're using this Keyword within the Cux method, it points to object2, and we're using that one to call logThis, with the specified this value. So that's object2. Hope that made some sense. Because, I'll show you in a second. And then the last one foo2, we are calling foo2 on object1.

So we're calling a regular function on an object. So that just points to the object that invoked it, object1. Makes sense somewhat? Good. I think this is the last one, I hope. So we have the regular logThis again, we have logThis, we have logThis in arrow, we have logThis nested.

And we're invoking logThis, logThis in arrow, and logThis nested. What gets logged? And the right answer to this one is A, its object, window, object. So first, what we have is we can have that regular logThis method. We're not calling it it's just a reference to the function object.

So we're calling it on object. Object is what creates the lexical environment for the function. So in that case, this points to object. Then we call logThisInArrow. We're calling it on object, but it's an arrow function. We don't care who calls it. With an arrow function, we care about where it's defined, or the lexical environment in which it's defined.

And in this case, the lexical environment is window. So this points to window for logThisInArrow. Now we have locked this nested, logThis nested itself is a regular function. So within that entire function body this points to object because we call it an object, but then the nested function loThis and it's an arrow function.

So in that case, this points to the lexical environment in which it was defined, which in this case is the environment of logThis nested. So there, this points to object because that's a regular method. And we're using the this value of logThis nested within nested function, because it just goes down that environment chain.

So I'm calling that and points to object. I hope that makes some sense. So if we were to call console log on the line before, const nestedFunc, it would have logged object, cuz that's just what this points to in that regular method on object. And we're pretty much just reusing that same this reference in that arrow function, which is why it points to object.

Make sense? [LAUGH]
>> Why is it that even though it's it's an arrow function that it doesn't,
>> Because with arrow function this points to the lexical environment in which it was defined. And in this case this nested func function was defined within the lexical environments of logThis nested.

It's really just the function object of arrow functions doesn't have its own dis value, but the function object of regular functions does have its own dis value. So when we try to access this in an arrow function, it's like, I can't find it on my own function object.

So I'll go down the environment chain, what we just saw previously, and there it does have it in it's environment record for the environment that it points to. Just keep in mind that this keyword is always different depending on what it like, are we calling regular function and arrow function to class, an event handler.

And then how are we calling it who was calling it? Anyway, okay, this is the last one. Surely this is the last one what one second. It is yes, okay the very last this this question. So we began we have object with logThis, logThis, logThis2, regular function with logThis enter that logThis.

And we have logThis enter with apply, and then we have logThis and logThis3 that we deconstruct from object. We call logThis and logThis2 on the window object. And then we have logThis and logThis2 on the object, object. So what would it log? Would it be four times Window?

Window object, window object. You can read the rest. All right, so the right answer is E. It's window, window, object, object. So first, we're calling logThis. It's a regular function again. So we're calling logThis that we just deconstructed on the window object. It doesn't matter that it was defined on object and that we then deconstructed it, doesn't matter because we're invoking it on the global object on window.

So this points to Window. Same for this too, well in that case we return apply, so it calls that function with a specified object that this should point to. But within logThis, this points to the object that invoked it, so the window object. So that's still window. And then the same applies to the other two calls on object logThis.

Well in that case we're calling out an object, it's a regular method, so this points to the object that called it object. And with logThis, this keyword within logThis2 points to the object. If we use that value to like apply that to logThis inner. So we're saying all right, that object that this should point to in logThis inner is the same this as the logThis2 which is object because that's what called it.

Yes, what?
>> Could you review one more time how .this and .then get evaluated under a named function and an object as opposed to an anonymous function?
>> This and then, wait, sorry. Could you, I'm gonna just show in. Well, it doesn't matter if it's an anonymous function or not.

It matters if it's an arrow function or regular function. I'm not sure if that's the question. If this was logThis arrow, then it doesn't matter if we're calling it as an object, because it's an arrow function. They don't care about who called it. They only care about where it's defined.

Now, of course, an object itself doesn't have a lexical environment. The lexical environment is the global lexical environment that we just saw with closures and stuff. Object is just, in that case, a property on the declarative record, and that contains a reference to the function object. An arrow function object, which doesn't have its own this value, so it needs to get the this value from the lexical environment, which in this case is.

So global this global this does which is essentially the same as like this global this. It just goes down the environment chain, if that makes sense.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now