JavaScript ‘this’ keyword: A beginner’s approach

Explicit ‘this’ declaration
Up until now, we have depended on the JavaScript runtime to help us determine what the value of this
should be. While this is fine in some cases, it yields undesirable results in other cases. Take this asynchronous function for instance, what do you think the output will be? Try this in the console.
let myObject3 = {
firstName: "Michael",
age: 20,
aboutMe: function(){
setTimeout(function(){
console.log(this.firstName + " is " + this.age + " years old")
},5000)
}
}
myObject3.aboutMe();
The aboutMe
method has a function that only executes after 5 seconds, so when it gets called, it ‘saves’ the function for later. When it eventually executes, it does so in the global scope and as such will return
undefined is undefined years old.
The reason this happened is simply because the keyword this
at the time of execution refers to the Window object, not myObject3 and since none of those properties exist within the Window object, it returns undefined. So how do we solve this problem? We have to somehow tell the Async function what the keyword this
is at any time of execution. JavaScript provides 3 ways to do this explicitly, call
, apply
and bind
.
The Call Method
The same way objects have predefined properties (prototypes) like toString
, functions have predefined methods too. One of those methods is call
. The call
method has many applications and use cases but ultimately solves one problem, which is setting the value of this
within the function it is called on.
Let take two separate objects for example, similar to the ones we used before
let user1 = {
name: "Tony",
sayHi: function(){
return this.name + " says Hi"
}
}
let user2 = {
name: "Martha",
sayHi: function(){
return this.name + " says Hi"
}
}
console.log(user1.sayHi()); //Tony says Hi
console.log(user2.sayHi()); //Martha says Hi
Both objects have the exact same function sayHi, which is unnecessary duplication of code. We can write this function once and use it in the second object by using the function’s call
method to determine the value of this
.
let user1 = {
name: "Tony",
sayHi: function(){
return this.name + " says Hi"
}
}
let user2 = {
name: "Martha"
}
console.log(user1.sayHi()); //Tony says Hi
console.log(user1.sayHi.call(user2)); //Martha says Hi
Here we used the user1 function sayHi
and used it’s call
method to determine the value of this by passing in the argument user2
. If the function had parameters, we can include the arguments in the call
method
let user1 = {
name: "Tony",
greet: function(msg, friend){
return this.name + " says " +msg+ " to "+friend
}
}
let user2 = {
name: "Martha"
}
console.log(user1.greet("Hi", "James"));
//Tony says Hi
console.log(user1.greet.call(user2, "Hello", "Habeeb"));
//Martha says Hello to Habeeb
The Apply Method
Similar to the call
method, the apply
method does the exact same thing with one exception, it only accepts one argument. If the function has more than one parameters, we must pass the arguments as an array.
console.log(user1.greet.apply(user2, ["Hello", "Habeeb"]));
Both call
and apply
executes the function they are called on immediately. This poses another problem when we want to use them in an Asynchronous function call like thesetTimeout
function we used before.
The Bind Method
Unlike call
and apply
, bind
returns the function it was called on but doesn’t execute it right away.
let myObject4 = {
firstName: "Michael",
age: 20,
aboutMe: function(){
setTimeout(function(){
console.log(this.firstName + " is " + this.age + " years old")
}.bind(myObject4),5000)
}
}
myObject4.aboutMe(); //Michael is 20 years old
This time, the correct message is displayed as intended. The bind
method just attaches the correct object reference to the this
keyword
So far we have seen 3 ways of explicitly setting the value of this
. There is a fourth way of doing the same thing, the new
keyword, but it is a bit beyond the scope of this article.
Posted from my blog with SteemPress : https://selfscroll.com/javascript-this-keyword-a-beginners-approach/
Warning! This user is on my black list, likely as a known plagiarist, spammer or ID thief. Please be cautious with this post!
If you believe this is an error, please chat with us in the #cheetah-appeals channel in our discord.
This user is on the @buildawhale blacklist for one or more of the following reasons: