this
keyword references an object. Using this
keyword we may access the properties and methods of a class/object. Previously, I discussed the use-cases of this
in this article. The summery is:
- If a function is not part of any object, it will simply reference the global window object.
- If a function is a part of an object, we call it as method. Inside a method
this
references the object.
The main problem arises when we use a function(i.e. a callback function) inside that method of an object, this
references the global window object and we may want to access(bind) the object and redefine the this
inside the callback function.
Let’s see the problem first:
const books = {
author: "john doe",
books: ["history", "english", "math"],
findBooks() {
this.books.forEach(function (item) {
console.log(`${this.author} like ${item}`);
});
},
};
books.findBooks();
Books is a simple object which has author and books properties and a method "findbooks".
"findBooks" simply logs the author and books information. Inside the "findBooks" function we have used a "foreach" method that has a callback function. Now the output should print:
‘john doe like history’,
‘jhon doe like english’
‘john doe like math’
So we see this.author
does not print the author name. So what’s happened actually? You see, this line of code console.log(
${this.author} like ${item})
is inside the callback function and the callback function is a regular function, has different execution context and references the window object(recalling the summery 1 above). In short, callback function is not a part of the object it is inside.
So how do we access the object using this
?
This is the concept behind binding data or binding object.
There are three different scenarios by which may access/bind the object inside the callback function.
1. Using Arrow function:
Unlike regular function, Arrow function uses the surrounding scope as the scope of this, So whatever the surrounding scope is becomes the scope of an arrow function.
const books = {
author: "john doe",
books: ["history", "english", "math"],
findBooks() {
this.books.forEach((item) => {
return console.log(`${this.author} like ${item}`);
});
},
};
books.findBooks();
Now, the callback function doesn’t have it’s own scope rather it uses the findbooks methods scope.
2. Explicit bind method:
So I was thinking, If we stick to the regular function(as callback), there must be a way to bind the object.
This question has an answer too. We may use bind method to get access the object.
const books = {
author: "john doe",
books: ["history", "english", "math"],
findBooks() {
this.books.forEach(
function (item) {
return console.log(`${this.author} like ${item}`);
}.bind(this)
);
},
};
books.findBooks();
this
inside the bind method creates a little confusion. But fear not! see, we have access to this (books) object inside foreach. So, bind method also have access too. Now the regular callback function is binded with this object.
3. Assigning ‘this’ to a variable:
const books = {
author: "john doe",
books: ["history", "english", "math"],
findBooks() {
let self = this;
this.books.forEach(function (item) {
return console.log(`${self.author} like ${item}`);
});
},
};
books.findBooks();
We have assigned this to a variable(self) and use it inside the callback function. It is basically the closure concept that will not be covered in this article. But what it does, we get access to the variable declared in the parent function inside the child function . In this way, the self variable gets the reference of this, and later we used it inside the callback function.
Top comments (0)