What’s “this”? In the simplest of terms, the JavaScript keyword refers to the object it belongs to on runtime, depending upon its (where it is called). this call-site However, understanding what it would refer to in any given context, requires a slightly deeper understanding of some relevant concepts, which will be covered in this article. Just to start with, can have the following values depending upon where it is accessed : this : refers to the global object. 1. By default this : refers to the global object. In mode, however, will be . 2. Inside a function this strict this undefined : refers to the owner object. (A method is a function that belongs inside an object. In other words, it’s a function that’s an object’s property.) 3. Inside a method this : refers to the element on which the event was triggered. 4. In an event this : refers to the global object. In strict mode, will be , just like any other function in a global context. 5. Inside an Immediately Invoked Function Expression (IIFE) this this undefined : When a fat arrow is used to define a function, it doesn’t create a new value for , instead, it keeps referring to the same object it was referring to outside of the function. 6. Inside a Fat-Arrow function ()=> this This article hopes to give you an understanding of how these values are assigned to this, and how this knowledge can be utilized to suit our requirements. Call-Site and Call-Stack As discussed in the last section, we got to know that this is a made for each function invocation, which entirely depends upon where exactly it was called. runtime-binding This location in the code where the concerned function was called, is called the . An understanding of determining the is crucial towards understanding what this would be bound to, at any given point of the execution. call-site call-site While finding the is generally as simple as locating where a function was called from, it might not always be that clear because of certain coding patterns that might obscure it. call-site Hence, it’s important to think about the , the stack of functions that have been called to get us to the current stage of the execution which we’re concerned with. call-stack Let us take a simple example to illustrate how a and could be determined. call-stack call-site By following the chain of function calls in order, you can determine the call-stack and call-sites. * Tip for determining call-stack Utilize the built-in JS provided with any modern browser’s developer tools. debugger In the execution of any JS code, you can set a breakpoint by using the keyword to stop the execution at that point in the browser. debugger , Let’s say, we add a breakpoint when was called. thunderbolt() The stops the execution at the custom breakpoint, and the function at that point can be viewed on the right side. debugger call-stack In the image above, we can see that the execution was stopped at the point where we mentioned the keyword, as soon as is called. At this point, we will not observe any execution of code that comes after the (just the , in this case). debugger thunderbolt() debugger thunderbolt() log Our primary point of interest right now, is the which is clearly illustrated on the right-hand side, same as we determined in the example above. at the bottom of the stack, refers to the initial global call to call-stack (anonymous) choosePikachu() . Binding rules for “this” Now that we understand what a and a is, we can learn about how a determines what will hold during execution. call-site call-stack call-site this There are which apply. First, let’s understand them , and then, their when multiple rules can apply to the . four general rules independently order of precedence call-site 1. Default Binding This is the default catch-all rule, when none others apply. It comes from the most common case of a function invocation, which a standalone function call. Let’s look at the below example. The variable declared in global scope is the same as declaring a property on the global object of the same name. ultraBall Inside , the reference to this defaults to the global object. Hence, we would see the value of getting logged. getPokemon() this.ultraBall However, if mode is in effect globally or inside , the object is not permitted default binding. In that case, we will see the error . strict getPokemon global TypeError : 'this' is 'undefined' 2. Implicit Binding If the call-site has a context object (if a function is called through an owning or containing object, as its property), implicit binding applies. The rule states that, when there is a context object for a function reference, it’s object that should be used for its method calls’ binding. that this Let’s look at a few examples to illustrate the different cases which can arise. Since the object is the for the call, is synonymous to . pikachu this getBaseSpeed this.baseSpeed pikachu.baseSpeed Let’s look at another example to see how only the top or last level of an Object property reference chain matters to the call-site for implicit binding. this As we can see, the value is still . That’s because the call to is bound to its direct caller, , which serves as its binding. In this context, the value is . baseSpeed 90 getBaseSpeed pikachu this baseSpeed 90 Let’s look at a few more examples to show common cases where implicit binding can seem unexpected. In this example, we have lost our implicit binding to in case of assigning to a different variable . Now, for , this refers to the global object ( takes place). Hence, for the call, will be . this pikachu pikachu.getBaseSpeed baseSpeedFunction baseSpeedFunction default binding this.baseSpeed 50 Now, a more common and not-so-obvious way this loss of implicit binding can occur is when we pass a callback function. Consider the following example : Once again, inside the callback function executor , we are effectively passing a reference to . Upon execution, will be bound to the object again (or throw a , if mode is enabled), instead of . executeFunction pikachu.getBaseSpeedfunction this global TypeError strict pikachu It’s quite common for function callbacks to lose their binding. Another unexpected outcome can arise when the function we’ve passed our callback to, intentionally alters the for the call. For example, Event handlers in popular JavaScript libraries often modify to point to the that triggered the event. this this this DOM element You are not really in control of how your callback function reference will be executed. So far, you don’t have any way of controlling the call-site to assign the binding you intended. This is where comes into play. explicit binding 3. Explicit Binding To resolve the unintended loss of with implicit binding, we can explicitly set the value of to a given object for a function call. this this There are several in-built methods that can help us achieve like : explicit binding , The bind() method is a method of the property. This means can be used by every single function. bind() Function.prototype bind() The method creates a new function that, when called, has its keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called. bind() this In other words, returns a new function that is hardcoded to call the original function with the context set as specified. bind() this The call() and apply() methods and are also methods of the property, with similar but slightly different usage. call() apply() Function.prototype The method calls a function with a given value and arguments provided individually. call() this Whereas, the method calls a function with a given value, and arguments provided as an array (or an ). apply() this array-like object Invoking with explicit binding by or allows us to force its to be the of function . Pokémon Pokémon.call() Pokémon.apply() this this PokémonExtension Also, a noteworthy aspect of the above example is that all instances of will bind their respective to the execution of within them. Such an explicit binding is also called PokémonExtension this Pokémon hard binding. 4. New Binding In JavaScript, there is really no such thing as “constructor functions”, but rather construction call of functions. When a function is invoked with new in front of it, otherwise known as a constructor call, the following things are done automatically. A brand new object is created (aka constructed) out of thin air. The newly constructed object is -linked. (Out of the scope of this article) [[Prototype]] The newly constructed object is set as the binding for that function call. this Unless the function returns its own alternate object, the new invoked function call will return the newly constructed object. automatically All binding rules in action It should be clear that the is the lowest priority rule of the four. default binding Let’s compare and with each other. implicit binding, explicit binding, new binding Implicit versus Explicit As we saw, the of with took precedence over its own as it did for the second case as well. explicit binding firstAttempt.catchPokémon secondAttempt implicit binding, Hence, is of higher precedence than . explicit binding implicit binding Implicit versus new So, is more precedent than . new binding implicit binding Explicit versus new? and or cannot be used together, so something like is not allowed to test directly against . But, we can still use a to test the precedence of the two. new call apply var fourthAttempt = new catchPokémon.call(firstAttempt); new binding explicit binding hard binding is hard-bound against , but did not change to , as we may have expected, but it remained . attemptBinder firstAttempt new attemptBinder(“Steelix”) firstAttempt.name "Steelix" "Onix" Instead, the hard-bound call to is able to be overridden with . Since was applied, we got the newly created object back, which we named , and we see that indeed has the value . attemptBinder("Steelix") new new secondAttempt secondAttempt.name "Steelix" Thus, the newly created is used, rather than the previously specified for . Effectively, is able to override . this hard-binding this new hard-binding The primary reason for this behaviour is to create a function that essentially ignores the , and presets some or all of the function’s arguments. this hard-binding Finally, determining “this” We can summarize the rules for determining this from a function call’s in their order of precedence. call-site, Here they are : Is the function called with ? If so, this is the newly constructed object Example, new (New binding). var attempt = new catchPokémon("Pidgey"); Is the function called with or , even hidden inside a ? If so, this is the explicitly specified object ( . Example, call apply bind hard-binding Explicit binding) var attempt = catchPokémon.call("Pidgeotto"); Is the function called with a context, otherwise known as an owning or containing object? If so, this is that context object ( . Example, Implicit binding) var attempt = firstAttempt.catchPokémon("Pidgeot"); Otherwise, this defaults to the object, or in mode ( global undefined strict Default binding). Summary Determining the binding for an executing function requires finding the direct of that function. this call-site Once examined, four rules can be applied to the call site, in this order of precedence. Called with ? Use the newly constructed object. new Called with or or ? Use the specified object. call apply bind Called with a context object owning the call? Use that context object. Default : in mode, object otherwise. undefined strict global Credits Official documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this You Don’t Know JS: this and Object Prototypes, by Kyle Simpson. Previously published at https://anmshpndy.com/how-well-do-you-know-this