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
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.
- 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!
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.