Operator: this
The this keyword in JavaScript references the context from which a piece of
code, such as a function, is called. However, since the value of this depends
on how a function is called, there can be certain difficulties.
Value of this
The this keyword, references an object that serves as the execution context
for a block of code. The value of this depends on how a function is called,
this can lead to the this context of a function changing depending on how
it is called.
These differences can lead to problems if you are not careful about which
context is actually being used.
Information about which context is passed to this when used can be found in
the MDN documentation.
When this is used in strict mode ("use strict";) this
may be of any value.
Example of problem
To better illustrate the problems that can arise from the this operator, I’d
like to show an example that I’ve encountered in practice.
In our very simple example, we have an application class that controls our application and a class that is responsible for converting objects:
Source code for the example
class App {
constructor(mapper) {
this.mapper = mapper;
}
greetPerson(name) {
console.log(this.mapper.mapNameToGreeting(name));
}
greetPeople(people) {
people
.map(this.mapper.mapNameToGreeting)
.forEach((greeting) => console.log(greeting));
}
}
class Mapper {
constructor() {}
mapNameToGreeting(name) {
return `It's a pleasure to meet you Mr./Mrs. ${this.mapNameToLastname(name)}.`;
}
mapNameToLastname(name) {
return name.split(' ')[1];
}
}
let mapper = new Mapper();
let app = new App(mapper);
app.greetPerson('John Doe');
app.greetPeople(['John Doe', 'Jane Doe']);
Our application allows us to greet a single person or multiple people. For this
our Application uses the Mapper class to create a greeting. Internally, the
Mapper uses its own method mapNameToLastname to extract the last name from
the name passed.
If we run this application now, we will get an error:
It's a pleasure to meet you Mr./Mrs. Doe.
/src/index.js:21
return `It's a pleasure to meet you Mr./Mrs. ${this.mapNameToLastname(name)}.`;
^
TypeError: Cannot read properties of undefined (reading 'mapNameToLastname')
We can see that the greetPerson method works as expected, but the
greetPeople throws an error. For some reason the this operator is
undefined in our Mapper leading to it trying to call the Method
mapNameToLastname on undefined, which isn’t possible.
The Problem? We are using the mapNameToGreeting method as a callback for the
Array.prototype.map method. For callbacks like the one of the map function
the this context is set to undefined.
To fix this problem we either have to wrap our call to mapNameToGreeting in
an Arrow function, which doesn’t change the context of this. Or we use
the second parameter of the map function which allows us to bind a specific
context to the execution of the method.
Arrow Function:
greetPeople(people) {
people
.map((name) => this.mapper.mapNameToGreeting(name))
.forEach((greeting) => console.log(greeting));
}
Bind Methode:
greetPeople(people) {
people
.map(this.mapper.mapNameToGreeting, this.mapper)
.forEach((greeting) => console.log(greeting));
}
Resources
Last updated 21 Feb 2025, 10:55 +0100 .
What did you like?
What went wrong?