What is `this`? Technical debt!

There are a plethora of articles not only here in DEV, but 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 lots of 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.

In this article, we will go over some of the reasons you might want to avoid this as well.

Implicit isn't good

this is an implicit value, which means that you're not defining it as an argument of your functions, as a variable, or anything like that. It's already defined for you. You might think for a second "that's great", but you have to consider that depending on where you are in your code, this changes, so you can't be 100% certain about what's its current value.

console.log(this); // Will log `globalThis`.

const object = {
	shouldLogObject() {
		console.log(this);
	},
};

object.shouldLogObject(); // Will log `object`

[1, 2, 3].map(object.shouldLogObject); // Will log `globalThis` 3 times (???)

const aFunction = function () {
	console.log(this);
};

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) {
		console.log(argument);
	},
};

object.shouldLogArgument("foo"); // Will log `"foo"`

[1, 2, 3].map(object.shouldLogArgument); // Will log `1`, `2` and `3`

const aFunction = function (argument) {
	console.log(argument);
};

aFunction("foo"); // Will log `"foo"`

// Will log the value of `argument`:
const arrowFunction = argument => console.log(argument);

aFunction("foo"); // Will log `"foo"`

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

The "solutions" are even worst

Some posts out there tell you that is "easy" to solve this kind of issue, by 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. 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 you write the class itself:
class Example {
	constructor() {
		this.doSomething = this.doSomething.bind(this); // 🤮
	}
}

If you don't use classes...

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

So is it useless to learn what this is?

No, you definitely need to know how this works, not to mention that there are lots of native APIs in the browser and the server that uses classes, and knowing how to deal with this is useful when working with them. My point is that you should avoid code that uses this to make your life and the lives of other devs better.

Closing thoughts

I wrote this article mainly because some folks that explain what this is, also try to "sell it" like something good, when it actually sucks, so go and learn how to deal with it if you encounter one this in the wild, but avoid it as much as possible in the code you author.

That's it. That's the post.

If you agree I would love to read scenarios where this messed with you, and if you disagree please comment on the reasons you believe is a good idea to rely on an implicit value like this.

Thanks for taking the time of reading!

Cheers!