Javascript. The “this” variable

An introduction to the variable “this” and how it takes its value

The global execution environment

To begin to understand the variable this, the first thing we must do is refer to the execution environment of our application.

window === this; // true
global === this; // true

Functions

Photo by Artem Sapegin on Unsplash
function foo() {
console.log(this);
}
foo(); // Window
function Person(name, email) {
this.name = name;
this.email = email;
}
const person = Person('Gerardo', 'gerardo@latteandcode.com');
console.log(person);
function Person(name, email) {
this.name = name;
this.email = email;
}
const person = new Person('Gerardo', 'gerardo@latteandcode.com');
console.log(person);

New

In Javascript we can add the new operator in front of the invocation of a function to convert this invocation into a constructor. It was what we did in the previous example when we called the Person function:

const person = new Person('Gerardo', 'gerardo@latteandcode.com');
console.log(person);

Methods

Okay, and what happens when we invoke a function that belongs to an object? That is, what value does this take when we invoke the method of an object?

const person = {
name: 'Gerardo',
surname: 'Fernández',
fullname: function() {
console.log(`${this.name} ${this.surname}`);
}
};
person.fullname(); // Gerardo Fernández
const person = {
name: 'Gerardo',
surname: 'Fernández',
fullname: function() {
return function() {
console.log(`${this.name} ${this.surname}`);
};
}
};
person.fullname()(); // undefined
name = 'Chrome'; 
surname = 'Window';
const person = {
name: 'Gerardo',
surname: 'Fernández',
fullname: function() {
return function() {
console.log(`${this.name} ${this.surname}`);
};
}
};
const printFullname = person.fullname();
printFullname(); // Chrome Window

Bind, call and apply

Therefore, this may lose the reference depending on the object that calls the function. To prevent this, there is the possibility of using the bind , call y apply functions in order to force the value of this in the invocation.

const person = {
name: 'Gerardo',
surname: 'Fernández',
fullname: function() {
const printFullname = function() {
console.log(`${this.name} ${this.surname}`);
};
return printFullname.bind(this);
}
};
const printFullname = person.fullname(); // bound
printFullname(); // `Gerardo Fernández`
const book = {
currentPage: 1,
gotoPage: function(page) {
this.currentPage = page;
console.log(`Current page: ${this.currentPage}`);
}
}
const gotoPage = book.gotoPage;gotoPage.call(book, 10); // Current page: 10
gotoPage.apply(book, [10]); // Current page: 10

Arrow functions

With the arrival of ES6, a new way of declaring functions was introduced that directly affects the value taken by this: the “arrow functions”.

const book = {
currentPage: 1,
readPage: function() {
setInterval(function() {
this.currentPage += 1;
console.log(this.currentPage);
}, 1000);
}
}
book.readPage();
var callback = function() { 
this.currentPage += 1;
console.log(this.currentPage);
}
callback(); // cada 1 segundo
const book = {
currentPage: 1,
readPage: function() {
setInterval(() => {
this.currentPage += 1;
console.log(this.currentPage);
}
, 1000);
}
}
book.readPage();
const book = {
currentPage: 1,
readPage: function() {
setInterval(() => {
this.currentPage += 1;
console.log(this.currentPage);
}, 1000);
}
}
const readPage = book.readPage;
readPage();

Classes

The classes in Javascript were also an addition to ES6 with the aim of making the transition from object-oriented programming languages easier. No, before 2015 there were no classes in Javascript. 😅

class Person {
constructor(name, surname) {
this.name = name;
this.surname = surname;
}
printFullname() {
console.log(`${this.name} ${this.surname}`);
}
}
const person = new Person('Gerardo', 'Fernández');
person.printFullname(); // Gerardo Fernández ✅
const foo = person.printFullname;
foo(); // Uncaught Type Error cannot read 'name' of undefined ❌

Final thoughts

As you have seen, the variable this can sometimes be a headache, especially in those moments when we lose the reference to its value as when we work with “event listeners” or timing functions.

Do you want to read more articles like this?

If you liked this article I encourage you to subscribe to the newsletter that I send every Sunday with similar publications to this and more recommended content: 👇👇👇

Entre paseo y paseo con Simba desarrollo en Symfony y React

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store