Hey, Have you find the "this" keyword always confusing. what does it exactly point to? there are just too many rules around the "this" keyword. let's tackle all of them one by one.
JavaScript has this keyword that behaves differently from other programming languages, which may confuse you at first.
In JavaScript, you can use this keyword in the global and function contexts.
"This" references the object of which the function is a property. In other words, this references the object that is currently calling the function.
const counter = {
count: 0,
next: function () {
return ++this.count;
}
};
counter.next();
In the above function the "this" refers to the counter object since when an Object is created using {} brackets this refer's to the Object Itself.
but what happens when we make an Object using Constructor functions
function SoftwareDeveloper() {
this.favoriteLanguage = 'JavaScript';
}
let developer = new SoftwareDeveloper();
When an Object is creating via invoking the constructor function with the new keyword. the "this" keyword is set to the newly created Object.
What happens to this variable when we call a method inside the function vs when we assign that method to a variable then call it?
The value of this depends upon how you call the function
const person = {
name:"piyush",
greet: function () {
console.log(`hey ${this.name}`);
},
};
const greet=person.greet;
greet();
// hey undefined
person.greet();
// Hey piyush
"this" keyword points toward what's in the left of the dot notation i.e in case of greet() this points toward the window object and in person.greet() this points toward the person Object.
Can you manually decide and alter the value "this" keyword points to?
We can manually decide the value of this in a function or method via call() , apply() and bind() method
call() , apply() and bind() method can be directly invoked onto a function itself. As a result, the receiving function will be invoked with a specified value, as well as any arguments passed in.
call()
call() is a method directly invoked onto a function. We first pass into it a single value to set as the value of this; then we pass in any of the receiving function's arguments one-by-one, separated by commas.
const mockingbird = {
title: 'To Kill a Mockingbird',
describe: function () {
console.log(`${this.title} is a classic novel`);
}
};
mockingbird.describe();
// 'To Kill a Mockingbird is a classic novel'
const pride = {
title: 'Pride and Prejudice'
};
mockingbird.describe.call(pride);
// 'Pride and Prejudice is a classic novel'
apply()
Just like call(), the apply() method is called on a function to not only invoke that function but also to associate with it a specific value of this. However, rather than passing arguments one by one, separated by commas -- apply() takes the function's arguments in an array.
const mockingbird = {
title: 'To Kill a Mockingbird',
describe: function () {
console.log(`${this.title} is a classic novel`);
}
};
const pride = {
title: 'Pride and Prejudice'
};
mockingbird.describe.call(pride);
// 'Pride and Prejudice is a classic novel'
mockingbird.describe.apply(pride);
// 'Pride and Prejudice is a classic novel'
Since call and apply both do the same thing which one do you choose?
call() may be limited if you don't know ahead of time the number of arguments that the function needs. In this case, apply() would be a better option, since it simply takes an array of arguments, then unpacks them to pass along to the function
Bind()
Alike the other methods we discussed above bind() method allows us to directly define a value for " this" keyword. bind() is a method that is also called on a function, but unlike call() or apply(), which both invoke the function right away -- bind() returns a new function that, when called, has this set to the value we give it.
const printName = {
name: 'Piyush',
print: function () {
console.log(`Name: ${this.name}`);
}
};
const newName = {
name: 'Tanay'
};
const newFunction=printName.print.bind(newName);
printName.print()
//Name : Piyush
newFunction()
//Name : Tanay