Hey everyone! In this article we are going to talk about THIS keyword in JavaScript.
This used to be a concept that confused everyone a little bit, so we will try to break it down for you so you can understand its uses and in what situations can it be useful. Let’s go!
What’s the THIS keyword?
When we use ‘this’ in our daily conversations it always has a context attached with it, right? For instance, the sentence “This is my house” can only make sense in two ways when you are inside the house or you point to the house you are talking about.
If in the middle of the street you say “This is my house” it doesn’t really make sense, because ‘this’ isn’t really pointing to anything.
If you have a picture of your house then regardless of the location you can point to the picture and attach the context to ‘this’, it will be like ‘this house(in the picture) is my house’.
Similarly in JavaScript, this
keyword will point to something according to the context it is in or we can point it to the thing we want using call
, apply
and bind
.
Also Read: Understanding – Call, Apply, Bind
This will make better sense when we see the different contexts this
can be defined in.
Global Context
When we create a JavaScript file, even if there are zero lines of code written in the file a few things are created. One of the things created is the window object.
The window object contains different properties and methods including things related to DOM.
So when this
is used alone in global context, this refers to the global object (window object in browsers).
For example,
let a = this; console.log(a); // Window {} this.name = 'Sunil'; console.log(window.name); // Sunil
Here, this.name
is the same as window.name
.
Function Context
From here onwards, things will get a little weird, so stick with us.
In JavaScript, we can call a function in the following ways:
- Function invocation
- Method invocation
- Constructor invocation
- Indirect invocation
Each function invocation defines its own context. Therefore, the this
behaves differently.
1) Simple Function Invocation
When this
is used in a function (non-strict mode), this
refers to the global object (window
object in browsers).
For example,
function greet() { // this inside function // this refers to the global object console.log(this); } greet(); // Window {}
Let’s take one more example:
function show() { console.log(this === window); // true } show();
When you call the show()
function, the this
references the global object, which is the window
on the web browser.
Calling the show()
function is the same as:
window.show();
Function with Strict Mode
When this
is used in a function with strict mode, this
is undefined
.
For example,
"use strict"; function show() { console.log(this === undefined); //true } show();
2) Method Invocation
When we call a method of an object, JavaScript sets this
to the object that owns the method.
Whenever we are calling functions inside object, it is known as method.
For example:
const person = { name : 'Sunil', age: 25, // this inside method // this refers to the object itself greet() { console.log(this); console.log(this.name); } } person.greet(); //{name: "Sunil", age: 25, greet: ƒ} //Sunil
In the above example, this
refers to the person
object.
When we access this
inside an inner function (inside a method), this refers to the global object.
For example,
const person = { name : 'Sunil', age: 25, // this inside method // this refers to the object itself greet() { console.log(this); // {name: "Sunil", age ...} console.log(this.age); // 25 // inner function function innerFunc() { // this refers to the global object console.log(this); // Window { ... } console.log(this.age); // undefined } innerFunc(); } } person.greet(); //{name: "Sunil", age: 25, greet: ƒ} //25 //Window { …} //undefined
Here, this
inside innerFunc()
refers to the global object because innerFunc()
is inside a method.
However, this.age
outside innerFunc()
refers to the person
object.
3) Constructor Invocation
When a function is invoked with the new
keyword, then the function is known as a constructor function and returns a new instance. In such cases, the value of this
refers to a newly created instance.
For example:
function Person(fn, ln) { this.first_name = fn; this.last_name = ln; this.displayName = function() { console.log(`Name: ${this.first_name} ${this.last_name}`); } } let person = new Person("Sunil", "Pradhan"); person.displayName(); // Prints Name: Sunil Pradhan let person2 = new Person("Ram", "Sharma"); person2.displayName(); // Prints Name: Ram Sharma
In the case of person.displayName()
, this
refers to a new instance person
, and in case of person2.displayName()
, this
refers to person2
(which is a different instance than Person
).
4) Indirect Invocation
In JavaScript, all functions are objects. They are the instances of the Function type. Because functions are objects, they have properties and methods like other objects.
To complicate the subject a little more, JavaScript provides three native methods that can be used to manipulate the way the this keyword behaves.
These methods are call
, apply
and bind
. Let’s see how they work.
let honda = { brand: 'Honda' }; let audi = { brand: 'Audi' }; function getBrand(prefix) { console.log(prefix + this.brand); } getBrand.call(honda, "It's a "); //It's a Honda getBrand.call(audi, "It's an "); //It's an Audi
In this example, we called the getBrand()
function indirectly using the call()
method of the getBrand
function.
We passed honda
and audi
object as the first argument of the call()
method, therefore, we got the corresponding brand in each call.
The apply()
method is similar to the call()
method except that its second argument is an array of arguments.
let honda = { brand: 'Honda' }; let audi = { brand: 'Audi' }; function getBrand(prefix) { console.log(prefix + this.brand); } getBrand.apply(honda, ["It's a "]); // "It's a Honda" getBrand.apply(audi, ["It's an "]); // "It's a Audi"
Lets see an example of bind
:
When we call a method of an object, JavaScript sets this
to the object that owns the method.
let car = { brand: 'Honda', getBrand: function () { return this.brand; } } console.log(car.getBrand()); // Honda
In this example, this
object in the getBrand()
method references the car
object.
Since a method is a property of an object which is a value, we can store it in a variable.
let brand = car.getBrand;
And then call the method via the variable.
let car = { brand: 'Honda', getBrand: function () { return this.brand; } } let brand = car.getBrand; console.log(brand()); // undefined
We get undefined
instead of "Honda"
because when we call a method without specifying its object, JavaScript sets this
to the global object in non-strict mode and undefined
in the strict mode.
Also Read: Understanding – Call, Apply, Bind
To fix this issue, we can use the bind()
method. The bind()
method creates a new function whose this
keyword is set to a specified value.
let car = { brand: 'Honda', getBrand: function () { return this.brand; } } let brand = car.getBrand.bind(car); console.log(brand()); // Honda
JavaScript This In Arrow Functions
Arrow functions don’t have own version of this
. They will always inherit from the parent.
const greet = () => { console.log(this); } greet(); // Window {...}
What can we expect this to log? same as with normal functions, window or global object.
Arrow functions don’t have their own ‘this’ keyword so they inherit the value of ‘this’ keyword from their direct parent when it is called.
Same result but with different reason. With normal functions the scope is bound to global object by default, arrows functions, as we said before, do not have their own this
but they inherit it from the parent scope, in this case the global one.
What would happen if we add “use strict”?
const greet = () => { 'use strict'; console.log(this); } greet(); // Window {...}
Nothing, it will log the same result, since the scope comes from the parent one.
Let’s take one more example:
const greet = { name: 'Sunil', // method sayHi () { let hi = () => console.log(this.name); hi(); } } greet.sayHi(); // Sunil
Here, this.name
inside the hi()
function refers to the greet
object.
JavaScript This In Event Listeners
Here this
keyword points to the element on which the event is handled or listened. Let’s understand by code snippet.
<body> <p>I hope you all are doing well.</p> <script> const text = document.querySelector('p'); text.addEventListener('click', function () { console.log(this); //<p>I hope you all are doing well.</p> }) </script> </body>
JavaScript This In Class Methods
It is similar to constructor invocation i.e. within a class this
point to the current instance of the class.
class Theatre { constructor(person, movie) { this.person = person this.movie = movie } display() { console.log(`${this.person} is watching ${this.movie}`) } } const sunil = new Theatre("Sunil", "Lagaan") const anil = new Theatre("Anil", "Fanaa") sunil.display() //output : Sunil is watching Lagaan anil.display() //output : Anil is watching Fanaa
Here the instances being sunil
and anil
.
Conclusion
Thanks for reading this post. Hope, this post will make you understand how this works in JavaScript 😎.
To summarize,
🤔 ‘This’ in JavaScript
JavaScript this keyword refers to the object it belongs to.
It has different values depending on where it is used:
1) Alone and independent, this refers to the global object (window).
2) In a regular function, this referes to the global object.
3) In a function with ‘strict’ mode, this refers to undefined.
4) In a method, this refers to its parent object.
5) Arrow functions will always inherit from the parent.
6) In an event, this refers to the element that received the event
7) When the “new” keyword is used, this will refer to the new object.
8) Within a class this point to the current instance of the class.
9) Call, bind, and apply can be used to set this value.
Three methods to bind this
keyword explicitly
- call(): It is used when one value or no arguments are to be passed to the function.
call(object, argument-1,...,argument-n)
- apply(): It is used when multiple value arguments are passed to the function. It allows us to pass array as a argument.
apply(object, array)
- bind(): It is similar to
call()
, only difference is it returns a brand new function, which can be invoked later.
Comments “this” if you got any doubt or suggestions? Let’s meet on next post with another JavaScript concept.
Have a beautiful day 🙂.
Add comment