The ‘this’ keyword refers to the context in which a function is being invoked. Sounds simple enough, but sometimes figuring out what that context is can be confusing at first.
Most of the time, 'this' refers to an object. Which object it is referring to depends on the context in which it is being invoked. However, by understanding the different invocation patterns, we can learn to understand the context of ‘this’. The five invocation patterns are: global reference, free function invocation, method invocation, explicit binding, and construction mode.
Global reference
If you use ‘this’ outside of a function, it will refer to the global window object. Simply logging the value of ‘this’ to the console, free of any other function call, will print something like this:
In fact, it will print a lot more to the console, but the point is that what is being printed is the global window object: an object that always exists in Javascript in the global scope.
Free function invocation
The second invocation pattern refers to when a function is called freely, not in reference to an object method. Here, ‘this’ will therefore reference the global window object as well.
In the printer function the value of this references the global object, which has a property “firstName” with a value of ‘Nathan’, which it prints to the console.
Another way to think of both global reference and free function invocation is a “default” binding; When 'this' is used inside of a function body but is not in reference to an object method, or is used outside of a function, the value of this defaults to the global object.
Method invocation, or implicit binding, refers to the ‘this’ keyword being used inside of a declared object.
Here the printer function is defined inside of myObj, therefore providing a context for this: printer is called as a method of myObj.
However this can cause confusion. Here we can see that if we define printer in the global scope, we can still pass the function as an object method, and the value of this will relate to myObj. However, if we declare a global variable defined with an object method, the global variable will not hold that object reference in memory. Invoking printer freely will assign the value of this to the global window object.
Explicit binding
We can explicitly set what we want the context of ‘this’ to be using the following functions: call(), apply(), or bind(). These are methods that can only be used by functions to change the context of what object this is referring to.
call()
Say you have a function that is called freely, so the context of this would resolve to the global window. Using call passes an object as it’s first argument, and call’s the function and changes the context of this value to said object. We are explicitly defining the context of this.
Here we can see that on each function call, the value of 'this' relates to the object being passed to printer.call();
call() can optionally take more arguments after the object argument, and can be passed individually.
apply() is similar to call(), however the additional arguments passed to apply must be passed as an array of arguments
So call and apply invoke the function with the given context and arguments. bind() returns a function with a fixed context for this.
.bind() performs similarly to call by taking on an object as it’s first parameter, and optional individual arguments following (not passed in an array, like apply). Bind() returns a new function that is bound to the context argument. We can store the function inside a new variable and call the function by calling this new variable.
Construction Mode
In construction mode, or new binding, ‘this’ is always bound to the instance of a new object. When the new function is initialized, the value of this will always refer to the new object, as it is given a context.
Here the Person function is a constructor function. Invoking the function with arguments will create an object in said structure. Invocation of the Person function will therefore provide a context for 'this': it will be bound to the new object.
A note on Arrow functions:
Arrow functions handle the keyword 'this' much differently, so the example functions used above would not yield the same results if simply swapped for arrow functions. Here is some further reading on arrow functions and 'this' if you are interested.
Top comments (1)
Hi