JavaScript ‘this’ keyword: A beginner’s approach

in #art7 years ago

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/
Sort:  

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:

  • Spam
  • Plagiarism
  • Scam or Fraud