Introduction
Hey Folks! I'm super excited to be writing my first-ever blog post and sharing my ideas with all of you. Whether you're here to learn, to be entertained, or just to read something new, I'm grateful that you've taken the time to check out my blog.
So this article is all about this
keyword in JS. We'll explore the different rules that determine the value of this
in different contexts. Well, this
is gonna be fun!
this
in Global Scope
In the global context, the value of this
refers to the global object, which is window
in a web browser environment.
For example:
if(true){
console.log(this)
}
//OUTPUT
//Window {window: Window {...}, self: Window ...}
So if we're outside a function then this
is always going to be window.
Now let's talk about what would happen inside a function (method).
this
inside Functions
If a function is called as a method of an object, the value of this
will be the object that the method is called on. Take this example from the TV series Breaking Bad:
const cook= {
name: 'Heisenberg',
sayMyName() {
console.log(this.name);
}
};
cook.sayMyName(); // "Heisenberg"
Here, the sayMyName
method is called on the cook
object, so the value of this
inside the method refers to cook
.
Also, there may be scenarios where you can't just add the function to an object as a method like we just saw.
In that case, you can set the value of this
explicitly using bind
, call
, or apply
methods.
Function.bind()
bind() method allows you to pass in the object as a parameter and this object will be used as the value of
this
insidesayMyName
function.const cook= { name: 'Heisenberg', sayMyName() { console.log(this.name); } }; sayMyName.bind(cook); // "Heisenberg"
So here we've created a new function with a fixed
this
value and optionally some arguments that are pre-filled when the new function is called.Function.call()
.call()
method is a function method that allows you to call a function with a specifiedthis
value and arguments provided individually.Let's take another Breaking Bad example to understand this better.
Suppose Walter is looking to hire Saul as his lawyer and he wants to discuss the terms of their agreement with him. However, he wants to do this in the context of their meth business, not in a regular lawyer-client meeting.
const methBusiness = { owner: 'Walter White', discussTerms: function(clientName, lawyerName) { console.log(`Let's discuss the terms of our agreement, ${clientName} and ${lawyerName}!`); } }; const saul = { name: 'Saul Goodman' }; methBusiness.discussTerms.call(saul, 'Heisenberg', 'Saul Goodman'); //"Let's discuss the terms of our agreement, Heisenberg and Saul Goodman!"
Here we used
.call()
method to execute thediscussTerms()
method withsaul
as thethis
value, and pass'Heisenberg'
and'Saul Goodman'
as arguments. TheclientName
andlawyerName
parameters of thediscussTerms()
function correspond to these arguments.So now we know why "Better Call Saul", right?
Function.apply()
.apply()
method is much similar to.call()
as we saw previously. The only difference is that instead of passing arguments individually, it accepts an array of arguments. For example:Let's say our protagonist Walter was a chef instead of a professional meth cook and wishes to cook chicken for Gus in his restaurant Los Pollos Hermanos.
const gus = { name: 'Gus Fring', cookFood: function(dish, cookingTime) { console.log(`Cooking ${dish} for ${cookingTime} minutes at ${this.name}!`); } }; const losPollos = { name: 'Los Pollos Hermanos' }; const dish = 'Chicken Burgers'; const cookingTime = 25; gus.cookFood.apply(losPollos, [dish, cookingTime]); //Cooking Chicken Burgers for 25 minutes at Los Pollos Hermanos!
We used the
.apply()
method to execute thecookFood()
method withlosPollos
as thethis
value, and pass[dish, cookingTime]
as an array argument.
this
inside Constructor functions
When we're dealing with constructor functions, this
refers to the object instance that we're creating.
Think of it like this: a constructor function is like a blueprint for building an object with certain properties and methods.
When we create a new object instance using that constructor function, this
is used to set the values of those properties and methods. Here's another Walter White example:
function MethCook(name, age) {
this.name = name;
this.age = age;
}
let walterWhite = new MethCook("Walter White", 50);
console.log(walterWhite.name); // "Walter White"
console.log(walterWhite.age); // 50
Inside the constructor function, this
refers to the walterWhite
object that is being created, and we use it to set the values of the object's properties.
this
inside Arrow Functions
When it comes to arrow functions, the behavior of this
can be a bit different than in regular functions.
Unlike regular functions, arrow functions do not have their own this
value. Instead, when this
is used inside an arrow function, it "inherits" the this
value from the code outside the arrow function.
const cook= {
name: 'Walter White',
letsCook(){
setTimeout(()=> {
console.log(this)}, 3000)
}
}
cook.letsCook()
//{name: "Walter White", letsCook: let...}
One important thing to note here is that, if we used the Callback Function instead of the Arrow Function in the above example, the result would differ. Let's see how:
const cook= {
name: 'Walter White',
letsCook(){
setTimeout(function {
console.log(this)}, 3000)
}
}
cook.letsCook()
//Window {window: Window {...}, self: Window ...}
Callback functions are run in an entirely different context. Just because this is written inside the constructor function doesn't mean it'll have binding between this
keyword and cook
object.
Hence the output comes out to be window
object.
Conclusion
So this was all about this
in JavaScript. I hope you found this post informative and engaging. While there may still be some information missing, I tried my best to share some valuable insights.
If you have any doubts or suggestions feel free to write a comment below or ping me on Twitter.
Enough of this
for the day, I'll see you in the next one 👋