Skip to main content

The 'this' Keyword

One aspect of JavaScript that often leads to confusion is the keyword this. Its value depends on where it is used and how that function is called.

this in a constructor

We saw previously that a constructor in a class is a special method which is used to instantiate on a new object. When used inside a constructor, this refers to the new object being created.

class Person {
constructor() {
console.log(this);
this.name = "Mike";
}
}

const person = new Person();

this in a method

A method is a function that belongs to an object. That object can be either be created as an object literal or using a class.

class Person {
constructor() {
this.name = "Mike";
}

sayHi() {
console.log(`Hi, ${this.name}`);
}
}

const person = new Person();
person.sayHi();

In both above example sayHi is a method which belong to person.

When a method is called, the value of this inside of that method will be the object that the method belongs to. In the example above that will be person.

this in a function

The value of this in a standalone function if it's executed in the browser will be the window object. If it is executed in Node it will be the global object.

function sayHey() {
console.log(this);
}

sayHey();

methods called as functions

We can take a method and assign it to a variable. Essentially that turns it from being a method into a standalone function.

class Person {
constructor() {
this.name = "Mike";
}

sayHi() {
console.log(`Hi, ${this.name}`);
}
}

const person = new Person();
const sayHi = person.sayHi;

sayHi(); // TypeError: Cannot read property 'name' of undefined

In above example, we are executing sayHi as a function, not method. As a result we no longer have access to the object the method belongs to. That results in the value of this being lost and instead of being person it is now undefined.

That can be a problem. Fortunately we can fix it

arrow functions to the rescue

Latest versions of JavaScript allow us to declare methods in classes using arrow functions. When an arrow function is used, the value of this inside it is bound to the object it belongs to. That allows us to call methods as functions without losing the value of this inside it.

class Person {
constructor() {
this.name = "Mike";
}

sayHi = () => {
console.log(`Hi, ${this.name}`);
};
}

const person = new Person();
const sayHi = person.sayHi;

sayHi(); // Hi, Mike

This behaviour will become important in the near future, when we will need to start passing methods to be called other parts of our code.

Exercises

In break out groups solve the following exercises. Only run code to verify answers. Try to understand what each line of code is doing and the effect it has.

// Exercise 1
class Car {
goFaster() {
this.speed = 100; // what is the value of this code below is run
}
}

const ferrari = new Car();
ferrari.goFaster();

// Exercise 2
class Car {
goFaster() {
this.speed = 100; // what is the value of this code below is run
}
}

const honda = new Car();
const quicker = honda.goFaster;

quicker();

// Exercise 3

// How can we fix the bug above? Why do have a problem and how does your solution fix it?