Jump to content

We don't need this

There are a plethora of articles all over the web about what is this in JavaScript. That’s because this is one of the most confusing topics about JavaScript for juniors, even if they are experienced in other programming languages.

There are many answers to the question “What is this?” but from my point of view, the answer is just one: “Technical debt,” and that’s because, for me, anything written using this, can and should be written without it.

Implicit isn’t good

this is an implicit value, meaning we do not define it like arguments, variables, etc. Instead, it is determined automatically for us. We might think for a second, “that’s great,” but we have to consider that depending on where we are in our code, this changes, so we can’t be 100% certain about its current value.

console.log(this); // Will log `globalThis`.
const object = {
shouldLogObject() {
object.shouldLogObject(); // Will log `object`
[1, 2, 3].map(object.shouldLogObject); // Will log `globalThis` 3 times (???)
const aFunction = function () {
aFunction(); // Will log `globalThis`
const arrowFunction = () => console.log(this); // Will log `globalThis`
aFunction.call("foo"); // Will log `"foo"`

Now, let’s see how this looks like if we don’t use this:

console.log("hello"); // Will log `"hello"`.
const object = {
shouldLogArgument(argument) {
object.shouldLogArgument("foo"); // Will log `"foo"`
[1, 2, 3].map(object.shouldLogArgument); // Will log `1`, `2` and `3`
const aFunction = function (argument) {
aFunction("foo"); // Will log `"foo"`
// Will log the value of `argument`:
const arrowFunction = argument => console.log(argument);
aFunction("foo"); // Will log `"foo"`

It is almost the same amount of code, but now it is pretty clear what everything does because we are explicit about it.

The “solutions” are even worst

Some posts out there present “easy solutions” to this kind of issue using some methods that come with a function: bind, call and apply. To me, that’s like putting patches over patches instead of fixing the root issue. For example, let’s say that we have a function that takes a callback called onEvent:

// with plain functions:
onEvent(doSomething); // readable, no issues here
// but with class methods:
onEvent(instance.doSomething); // will break if it uses `this`
// to "solve" that:
onEvent(event => instance.doSomething(event)); // verbose
// or
onEvent(instance.doSomething.bind(instance)); // wth?!
// or when we write the class itself:
class Example {
constructor() {
this.doSomething = this.doSomething.bind(this); // 🤮

If we don’t use classes

I already have a post about why we don’t need classes to code, and this post is related, mainly because this is extremely common when working with class. Some might even say that if we work with static methods and stuff like that, then we don’t use this, but my answer is: Why are we even using class then? We could have those static methods be functions in a module and use them directly.

So is it useless to learn what this is?

No, we need to know how this works, not to mention that there are many native APIs in the browser and the server that uses classes, and learning how to deal with this is useful when working with them. However, we should avoid code that uses this to improve our lives and the lives of other developers.

Closing thoughts

I wrote this article mainly because some folks are explaining what this is and trying to “sell it” like something good when it’s something awful. So, everyone should learn how to deal with this if we encounter one in the wild, but avoid it as much as possible in the code we write.