What's the value of this in JavaScript?
Basically, this
refers to the value of the object that is currently executing or invoking the function. I say currently due to the reason that the value of this changes depending on the context on which we use it and where we use it.
const carDetails = {
name: "Ford Mustang",
yearBought: 2005,
getName(){
return this.name;
},
isRegistered: true
};
console.log(carDetails.getName()); // logs Ford Mustang
This is what we would normally expect because in the getName method we return this.name
, this
in this context refers to the object which is the carDetails
object that is currently the "owner" object of the function executing.
Ok, Let's some add some code to make it weird. Below the console.log
statement add this three lines of code
var name = "Ford Ranger";
var getCarName = carDetails.getName;
console.log(getCarName()); // logs Ford Ranger
The second console.log
statement prints the word Ford Ranger which is weird because in our first console.log
statement it printed Ford Mustang. The reason to this is that the getCarName
method has a different "owner" object that is the window
object. Declaring variables with the var
keyword in the global scope attaches properties in the window
object with the same name as the variables. Remember this
in the global scope refers to the window
object when "use strict"
is not used.
console.log(getCarName === window.getCarName); //logs true
console.log(getCarName === this.getCarName); // logs true
this
and window
in this example refer to the same object.
One way of solving this problem is by using the apply
and call
methods in functions.
console.log(getCarName.apply(carDetails)); //logs Ford Mustang
console.log(getCarName.call(carDetails)); //logs Ford Mustang
The apply
and call
methods expects the first parameter to be an object which would be value of this
inside that function.
IIFE or Immediately Invoked Function Expression, Functions that are declared in the global scope, Anonymous Functions and Inner functions in methods inside an object has a default of this which points to the window object.
(function (){
console.log(this);
})(); //logs the "window" object
function iHateThis(){
console.log(this);
}
iHateThis(); //logs the "window" object
const myFavoriteObj = {
guessThis(){
function getThis(){
console.log(this);
}
getThis();
},
name: 'Marko Polo',
thisIsAnnoying(callback){
callback();
}
};
myFavoriteObj.guessThis(); //logs the "window" object
myFavoriteObj.thisIsAnnoying(function (){
console.log(this); //logs the "window" object
});
If we want to get the value of the name
property which is Marko Polo in the myFavoriteObj
object there are two ways to solve this.
First, we save the value of this
in a variable.
const myFavoriteObj = {
guessThis(){
const self = this; //saves the this value to the "self" variable
function getName(){
console.log(self.name);
}
getName();
},
name: 'Marko Polo',
thisIsAnnoying(callback){
callback();
}
};
In this image we save the value of this
which would be the myFavoriteObj
object. So we can access it inside the getName
inner function.
Second, we use ES6 Arrow Functions.
const myFavoriteObj = {
guessThis(){
const getName = () => {
//copies the value of "this" outside of this arrow function
console.log(this.name);
}
getName();
},
name: 'Marko Polo',
thisIsAnnoying(callback){
callback();
}
};
Arrow Functions does not have its own this
. It copies the value of this
of the enclosing lexical scope or in this example the value of this
outside the getName
inner function which would be the myFavoriteObj
object. We can also determine the value of this
on how the function is invoked.