‘This’ is fine. Evaluating the value of the javascript keyword ‘this’.
In coding, few things incite mass confusion and panic more than the keyword ‘this’. What is ‘this’? How did ‘this’ get here? Who does ‘this’ belong to? WHAT DOES ‘THIS’ MEAN?? Even asking valid questions about ‘this’ make you seem half-crazed. It’s fine, calm yourself, we’re going to go on this journey together. Let’s talk about evaluating the value of the keyword ‘this’ in javascript.
Simply put, ‘this’ is a keyword that points toward an object. It’s often defined within a function, but it can be used safely in most other contexts without throwing an error (although it’s likely not to represent the value you’re looking for, unless you’re looking for some really weird values). The paramount thing to remember when considering ‘this’ is to be mindful of when ‘this’ was called, as opposed to when ‘this’ was declared. Declaration has no power over the keyword ‘this’, it floats through the code without meaning or value until BOOM - the code is called, and now ‘this’ points to an object, based entirely on when it’s called in the program. So it’s safe to disregard how ‘this’ was declared or when it was defined, and focus entirely on how and when ‘this’ was invoked. Still with me? No? Don’t worry, we’ll get there together. Follow me.
There are 6 major methods for determining the value of ‘this’ when reviewing code. When seeking to determine the value of ‘this’, follow through this list and you should be able to determine the value of ‘this’. These invocations of ‘this’ are as follows, in the order we’ll be reviewing them:
- Global reference
- Free function invocation
- Call, Bind, or Apply
- Method invocation
- Construction Mode
- Arrow Functions
Global reference - I’d be hard pressed to think of a time when you’d want to do this on purpose. Still, you are more than welcome to declare ‘this’ out in the open, without cause or constraint. In this case, ‘this’ still has to point to something. In most cases, ‘this’ will point to the Global Object, the Object Above All Other Objects, the Master Object, His High Holiness Lord Object, aka the Global Window. In javascript, most ‘things’ are, in fact, objects, and most of your code is running inside of a giant object- the ‘window’ that holds the prototype properties for all the objects contained within it. So when you use ‘this’ in the global scope, it will point to the global object, and seek out keys attached to that object. This can produce unexpected results if you’re not careful. Any variable declared with the keyword ‘var’ becomes attached to the global window and can be accessed using ‘this’ (with the implementation of ES6, keywords ‘const’ and ‘let’ do NOT attach to the window, so these are safer to use if you’re not looking for surprise connections). As you can see in the example below, ‘this’ can be referenced to show us that it Run’s House.
Free Function Invocation - Any time a function is called freely, we call this a free function invocation. These can be great for compact pure functionality, existing free of any other systems, unattached from other objects. However, these can be awful when using the keyword ‘this’. The result of using ‘this’ with a FFI is that ‘this’ points, once again, to the global window. If I were a betting man (I am not, unless you’ve got a solid line on a horse that can’t lose), I’d say that 90% of all missed ‘this’ connections (‘thissed’ connections, as we call them in the ‘biz’) end up pointing to the global window unintentionally. In this example, we create a function that asks the classic question, “Who’s House?” We can see here, using an FFI, that it is still definitely Run’s House.
Call, Apply or Bind - Oh these guys. They are the Huey, Duey, and Luey to ‘this’s Scrooge McDuck. Largely the same, with slightly different colored hats to tell them apart, Call, Apply, and Bind are powerful tools in manipulating the keyword ‘this’ into representing values that we choose for it. Call and Apply work largely the same, and are often interchangeable (the main difference between the two is how arguments are fed in, but we’ll discuss that on another day). Both take an argument and attach ‘this’ to that argument before calling the method attached to ‘this’. Sounds obtuse, but it actually creates a direct visualization of where ‘this’ is going to point. We’ve got our “Who’s House?” function back again, and we call it a couple of times here. Normally, this would be Run’s House, but we use Call and Apply to send ‘this’ chasing after those values. In the cases of these two invocations, now Call and Apply cause ‘this’ to point to Big Mama’s House and Flo Rida’s House respectively.
Bind operates a little differently than it’s two cousins. While Call and Apply will fire the method immediately, Bind does not fire the method. Instead, it attaches an argument to the method and creates and entirely new function that can be invoked later. These connections are permanent, so Bind cannot be reassigned. Doing so would be absolute folly. If you’re looking to reassign using something that’s already bound, you’re just going to have to create ANOTHER function. In this example, our global name is Big Mama. We create an object with a name property, Kid N’ Play, with a method that once again determines “Who’s House?”. We see below how the value of ‘this’ can change, and how we can reattach it to Kid N’ Play using the power of BIND! It is now Kid N’ Play’s House.
Method Invocation - Speaking of methods, here we are! Methods are the most common...well, method of determining the value of ‘this’. Lucky for us it’s also one of the easiest. When a method is called utilizing the keyword ‘this’, we simply look to the left of the dot preceding the method call. That’s what ‘this’ will point to. It’s that easy! We don’t even have to dwell here long, it’s so simple. In the example below, when whosHouse is called as a method, we simply look to the left of the dot. We see obj1 and obj2, and in each case ‘this’ points to those objects. We’re back with Big Mama’s House and Flo Rida’s House. See, ‘this’ isn’t so hard, is it? I knew you’d start having fun eventually.
Construction Mode - Often when we start using construction functions, we’ll be implementing the keyword ‘this’. When we do this, it’s imperative to remember that ‘this’ won’t ever point to the constructor itself. Instead, ‘this’ will point to whatever new instance of the constructor we’re looking at. Here we use the ‘new’ keyword to create a new object, a better object, a uniquely Kid N’ Play object. When we call the whosHouse function, ‘this’ will therefore refer to this new object, and not the constructor object used to build it. Did you know that the House Party movies were originally written with Will Smith and DJ Jazzy Jeff in mind? Well, you do now. Moving on.
We’ve got one last factor in determining the value of ‘this’, but first let’s talk about the hierarchy of lookups when determining ‘this’. Javascript will try and assign ‘this’ based on the presence of certain factors. They are, in order of importance:
- First it checks whether the function is called with new keyword. Instances of constructor functions get first priority.
- Second, it checks whether the function is called with call, bind or apply. As you would imagine, these mask over other bindings and supercede them.
- Third it checks if the function called via context object. This is our common method invocation. Look to the left of the dot!
- Finally, Javascript will look to the global window. If ‘this’ is evaluating to something really strange, it’s probably pointing here.
Arrow Functions - I’ll only touch on them briefly here, because honestly Arrow Functions deserve their own post (as with much of ES6’s implementation, it’s a feature that I’m eager to talk about at length). Arrow functions are a newer concern, but with the spread of ES6 conventions, they’re becoming more common. Arrow functions have an interesting effect on ‘this’. As opposed to every other method, they will bind ‘this’ to the lexical scope in which it is declared. All that stuff I said about not worrying about where ‘this’ is declared? In this case, throw that out the window. Arrow Functions can be a powerful way to bend ‘this’ to your will, or they can throw your entire code off course if you’re not paying attention (this has happened to lesser men than me, but never me, no sir). Either way, I plan on writing a larger post on the power of Arrow Functions, and we’ll touch on ‘this’ further therein.
So that’s it for now! ‘This’ really isn’t that scary once you understand the contexts in which it can be invoked. Once you understand those contexts, it’s only a matter of evaluating them at runtime to see where ‘this’ will lead you. Until then- Who’s House? RUN’S HOUSE.
Top comments (0)