If you are working with JavaScript for a while, you will agree with me. This ‘this’ keyword is very confusing when you are writing code, especially when you read others’ code.
This article’s goal is to eradicate those confusions. You have to remember a few things about ‘this’ and consider where you are using it and how you are using it.
So let’s start:
In the global execution context
Type the following line in your browser console.
// 'this' in global context
console.log(this); // here 'this' refers to global object, if browser it is 'window' and in nodeJS it is 'global'
So in the global context, ‘this‘ refers to the global object. The browser refers to the ‘window‘ object, and if nodeJS, it refers to the ‘global’ object.
In a function which is in the global execution context
In a function in a global context, ‘this’ refers to the global object; in a browser, it refers to ‘window’.
function testFunc() {
console.log(this);
}
testFunc(); // it will log 'window' object
But when you use strict mode by ‘use strict’, in the same use in a function, it will refer to ‘undefined’
'use strict'
function testFunc() {
console.log(this);
}
testFunc(); // it will log 'undefined'
In a function when it’s initiated with the ‘new’ keyword
If a new instance of a function is created with the ‘new‘ keyword, then ‘this’ inside the function will refer to the object’s instance.
function Address(country, state, city, zip) {
this.country = country;
this.state = state;
this.city = city;
this.zip = zip;
this.printAddress = function() {
console.log(this);
console.log('Country: ' + this.country + ', State: ' + this.state + ', City: ' + this.city + ', Zip: ' + this.zip);
}
}
let myAddress = new Address('myCountry', 'myState', 'myCity', 1000);
myAddress.printAddress();
// for console.log(this), it will print
// Address {country: "myCountry", state: "myState", city: "myCity", zip: 1000, printAddress: ƒ}
// for address console.log it wll print
// Country: myCountry, State: myState, City: myCity, Zip: 1000
In a function that belongs to an object
When used in a function in an object, ‘this‘ will refer to that object.
let address = {
country: 'myCountry',
state: 'myState',
city: 'myCity',
zip: 1000,
printAddress: function() {
console.log(this);
console.log('Country: ' + this.country + ', State: ' + this.state + ', City: ' + this.city + ', Zip: ' + this.zip);
},
};
address.printAddress();
// here console.log(this) print the 'address' object
// {country: "myCountry", state: "myState", city: "myCity", zip: 1000, printAddress: ƒ}
// and the second console.log prints
// Country: myCountry, State: myState, City: myCity, Zip: 1000
In function prototype methods like call(), apply() or bind()
It is possible to set a custom object for ‘this’ using the function prototype methods. Like with call() or apply(), you can do something like this:
function Address(country, state, city, zip) {
this.country = country;
this.state = state;
this.city = city;
this.zip = zip;
this.printAddress = function() {
console.log(this);
console.log('Country: ' + this.country + ', State: ' + this.state + ', City: ' + this.city + ', Zip: ' + this.zip);
}
}
let myAddress = new Address('myCountry', 'myState', 'myCity', 1000);
let yourAddress = new Address('yourCountry', 'yourState', 'yourCity', 2000);
myAddress.printAddress.call(yourAddress);
// for the first console.log it will log
// Address {country: "yourCountry", state: "yourState", city: "yourCity", zip: 2000, printAddress: ƒ}
// for the second console.log it will print
// Country: yourCountry, State: yourState, City: yourCity, Zip: 2000
The same thing can be done with bind():
function Address(country, state, city, zip) {
this.country = country;
this.state = state;
this.city = city;
this.zip = zip;
this.printAddress = function() {
console.log(this);
console.log('Country: ' + this.country + ', State: ' + this.state + ', City: ' + this.city + ', Zip: ' + this.zip);
}
}
let myAddress = new Address('myCountry', 'myState', 'myCity', 1000);
let yourAddress = new Address('yourCountry', 'yourState', 'yourCity', 2000);
let addressPrint = myAddress.printAddress.bind(yourAddress);
addressPrint();
// for the first console.log it will log
// Address {country: "yourCountry", state: "yourState", city: "yourCity", zip: 2000, printAddress: ƒ}
// for the second console.log it will print
// Country: yourCountry, State: yourState, City: yourCity, Zip: 2000