Credits: Pixabay.com Your knowledge of JavaScript can be pretty well judged by your understanding of . The fact that people find it difficult to comprehend is, because of its use in multiple and varied scenarios. this Let's get them right once and for all. If I were to talk about in the literal sense, it simply means — this very thing in front of me. “This Jacket is Cool”, claimed my sister holding that jacket in her hand. I replied back saying, “No, this one’s better!” I was referring to the jacket near to me and she was referring to the one near her and hence the use of in respective statements. this this Value of this depends on1. The Execution Context2. Invocation Execution Context Execution Context is the environment in which the code runs. For example, the local variables of a function would be accessible in that function only and not outside of it. This is called as Functional Level Scoping or Local Execution Context. Variables declared in global scope (outside of any function) would be accessible in all the underlying functions. This is called the . Global Execution Context Let’s consider this example to understand the difference between the two of them - The value of in Global Execution Context by default is object. this window The value of in any Local Context depends on the way the function is called. this I. Calling a function in the global context would have its value as this **window** II. Calling a function that runs JavaScript statements in strict mode would have as this undefined III. Calling a function that is inside an object Function is one of the properties on object . When we call with reference to as , it gets called in the context of . Properties & have definite value in the context of so that result of is defined. add obj add obj obj.add() obj a b obj , obj.add() The variable stores the reference of function. If we execute this function at a later stage, it will run in the context from where it is called. In our example, we’re calling in the global context, so it will have a global object as reference. Since and are not defined in the global context, we’re getting the value of as . cacheAdd add cacheAdd this a b a+b NaN To prove this point, let's define and in the global context. a b evaluates to 3 as the value of and defined in obj is 1 & 2 respectively. When we run after caching it in a variable and then executing it in the global context, it evaluates to 7 as the value of a & b in the global context is 3 & 4 respectively. So, a function that uses may give a different result depending on the context in which it is executed. obj.add() a b add this Let's try another interesting example — In this case, add function returns another function and the value of is executed in this inner function. will return a function that has one statement. So, we’ve to execute this returned function in order to get the sum of a & b. But this returned function (returned on executing ) will run in the global context and hence the value of a+b evaluates to 7 (Value of a & b in the global context is 3 & 4 respectively). a+b obj.add() console _obj.add()_ Here, add function prints the value of a & b after a timeout of 500ms. runs in the global context. setTimeout Why setTimeout runs in the global context? (I’ll explain about it in detail in my next post.) takes the reference of the immediate object calling the function this Here, has as one of the properties and add function is defined on . When we call add as , add function takes the reference of and variables a & b are not accessible from the local context of . Hence the value of a & b is . parentObj childObj childObj parentObj.childObj.add() this childObj childObj undefined Linking to the prototype chain If we instantiate to create , its properties would be accessible in the context. parentObj childObj childObj Using Object.create When add function gets called in the context of , it first tries to look for values of a, b & c in the context of and if any of these values is , it looks up to its parent context, which in this case is . childObj childObj undefined parentObj Using operator new In this case, properties of parent are available in the context of the child. As we can see in the trailing console statement, the constructor of the child is defined as Parent. So, it first checks for values in the context it is called and then look up to its prototype chain. This ain’t Rocket Science! By default, the code runs in a global context i.e. it has access to the variables defined in the context of the object. In each of the above cases, we’re just restricting the context to object. All the operations related to this would be carried out in the exact same way as they would have if the context was . Even with global context, if any of the values is not defined, it looks up to the prototype chain. window obj window As we can see, function is defined in property of , which means it is defined on the prototype of (Because is created by applying the operator to ). As is not defined in the context of , it looks up to its prototype chain. toString ___proto___ _obj_ Object obj new Object toString obj Let’s solve an interesting issue here — My sister stubbornly refuses to share the candy with me and to support her claim, she says, she is the owner of this candy. This is her Candy — So, somehow I’ve to modify reference that her function is using. The little toddler doesn’t know that JavaScript is an unconventional language. You can always mend it the way you want. this whosCandyIsThis Call, Apply & Bind — Here I go! With these 3 beautiful functions, you can modify the value of reference. In the above example, modifies reference of function to . this candy.whosCandyIsThis.call(myCandy) this whosCandyIsThis myCandy explicitly pass reference to a function. In this case, it tells function to use as . What is call all about? call this whosCandyisThis this myCandy The first argument of call is reference and if we have to pass in any additional parameters, you can do something like this this candy.whosCandyisThis.call(myCandy, true)` Let’s consider one more example: Here, we’re passing reference explicitly to the function defined in the hotel object to display the menu accordingly. (Isn’t this cool?) this displayMenu But what if I want to display the menu based on the user’s location. For that, we’ll pass an additional parameter to the function. Let’s modify the above code to fit in our requirements. location displayMenu The first parameter of is reference and then you can pass in any number of arguments that you want. The function now very well shows the list of menu items as per the parameter. (Sounds good?) call this displayMenu location operates in the same way as of , the only difference being the way in which we pass arguments. Apply takes in the first parameter as reference same as that of call but other parameters are to be passed as an array. apply call this Another function that can modify reference is . Unlike and that returns the result of the function, returns a function. And this returned function can then be called at any later stage. It will run in the context of the explicitly passed bounded argument. this bind call apply bind returns a function that has reference of . When we run , it runs in the context of and hence prints Espresso for location A. _hotel.displayMenu.bind(ccd)_ this ccd boundFunction ccd I was trying to experiment with my instincts. If I bind an already bounded function to some other reference, would that function run in the context of the later binding? If this is true, I can do this endlessly and keep changing this reference with all the power I have! This is not true. You can only bind a function once. In the above example, I’ve tried to bind the bounded function again with but when I execute this function, it prints the previous result which means its reference still points to the first binding ( ). pizzaCentre ccd Well again, JavaScript is an unconventional language. If there’s freedom to modify anything as you wish, there are guards who protect the integrity. One such masterpiece is our cute Arrow Function. This is how it works. Plain & Easy. Why are we even talking about arrow functions in this article? What’s so special about them? In the arrow function, the value of is that of its enclosing lexical context It does not change with the , or this Lexical Context is block level scoping. call apply bind . Arrow functions maintain the binding of this of its enclosing lexical context. Crape! This Fat Arrow took away my candy. As you can see, is defined as an arrow function. So it will maintain the binding of its . On instantiating Candy, sets the owner and flavor for her candy. function gets bounded to reference. whosCandyIsThis Lexical Context niks whosCandyIsThis niks So, When I try to call it explicitly by passing reference using call, apply or bind, it doesn’t work. The bindings of function cannot be changed, whatsoever! this niks.whosCandyIsThis You might like my previous articles on Service Workers — — Service Workers Fundamentals https://hackernoon.com/service-workers-62a7b14aa63a — Building Pokemon App to evaluate the power of Berries & Service Worker https://hackernoon.com/building-pokemon-app-to-evaluate-the-power-of-berries-service-worker-176d7c4e70e3