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.
*/
Top comments (8)
Thank you for sharing! For retro compatibility you can use
bind()
on the function passed as argument at theforEach
That's correct!
Thank you.
thanks ya handasa tslam edak ♥♥
7abeby ❤️
Makes sense! Thank you for the simple explanation🙌
You are welcome ^_^
Good job
Thank you.