In this article, we will remove the confusion of the this keyword in JavaScript.
First, we need to understand the difference between a function and a method.
A function is a block of code to perform a particular task and it Stands Alone.
example:
function sayHello() {
console.log("Hello")
}
sayHello(); // Hello
A method is also a function but it is inside an object
example:
const person = {
name: "John",
sayHello: function(){
console.log("Hello");
}
}
person.sayHello() // Hello
So, if this is inside a method, this will refer to the Object itself.
example:
const person = {
name: "John",
sayHello: function(){
console.log(this);
}
}
person.sayHello();
/*{
name:"John",
sayHello:f sayHello {...}
}*/
And, if this is inside a function, this will refer to the Global Object which is the window Object in Browsers and the global Object in Node.
example:
function sayHello(){
console.log(this);
sayHello(); //:[object Window]
The Constructor Function.
We use a constructor function to create a blueprint of an Object.
And because of this, the this keyword will refer to the created object.
the new keyword creates a new empty object { }
example:
function Person(name) {
this.name = name;
this.log = function(){
console.log(this);
}
}
const p1 = new Person("John");
const p2 = new Person("Doe");
p1.log();
/* Person {
name:"John",
log: {...}
}*/
p2.log();
/*Person {
name:"Doe",
log: {...}
}*/
The Confusion Starts Here.
Consider this code and try to guess what the this will refer to.
const person = {
fName: "John",
skills: ["HTML", "CSS", "JS"],
logSkills: function(){
this.skills.forEach(function(skill){
console.log(`${this.fName} can do ${skill}.`)
})
}
}
person.logSkills();
Is your answer =>
John can do HTML
John can do CSS
John can do JS?
Unfortunately, your answer is wrong.
the correct answer is =>
undefined can do HTML
undefined can do CSS
undefined can do JS
since this.fName will be undefined.
because this will refer to the window object, and window.fName is undefined.
But why you may wonder? isn't function(skill){ } is inside the person object?
Well, this not quite right.
The this is inside a callback function.
And a callback function is just a regular function.
So, this will definitely refer to the window object.
That's why we tend to use Arrow Functions as callback functions Since it Does not have its own bindings to this.
Now when we substitute a regular callback function to an Arrow Function you will get the result you expected.
const person = {
fName: "John",
skills: ["HTML", "CSS", "JS"],
logSkills: function(){
this.skills.forEach((skill)=>{
console.log(`'${this.fName}' can do '${skill}'.`)
})
}
}
person.logSkills();
/*
John can do HTML.
John can do CSS.
John can do JS.
*/
Latest comments (8)
Good job
Thank you.
Thank you for sharing! For retro compatibility you can use
bind()on the function passed as argument at theforEachThat's correct!
Thank you.
Makes sense! Thank you for the simple explanation🙌
You are welcome ^_^
thanks ya handasa tslam edak ♥♥
7abeby ❤️