Recently I have an argument with a friend who absolutely hate the this keyword in Javascript. He claims that since the language has an ambiguous binding of this in different situations, e.g. const f = obj.g will lose the binding to obj, obj.g.call(obj2) will call g in the context of obj2..., the this keyword in Javascript is simply one of the worst thing in Javascript.
He also claims that Javascript would be a lot easier to code/maintain by avoiding the use of this keyword. He advocates the following pattern for object creation:
function Car() {
const car = {};
car.position = 0;
car.move = () => car.position++;
return car;
}
new Car();
// or
Car();
I am, on the other hand, very comfortable with the this keyword. I use it a lot and appreciate how bind, call and apply works. However, I can't really find a legit argument against his pattern, because it really seem to be clearer for those who don't know much about Javascript?
What do you think? Give me some insights!
Latest comments (39)
this is an example of a language shooting for maximum flexibility — and having maximum flexibility shoot you back.
Disagree, when you use code that clones and appends elements, handling the new elements can be done so dynamicly with 'this'.
I don't understand. Can you elaborate what you mean? :)
As long as you are using some other library/framework you will always have to deal with "this". At least we have arrow functions now to avoid the "that". MJP of Fun Fun Function fame on YouTube refers to this as a "clown rainbow trap." Watch here youtube.com/watch?v=ImwrezYhw4w.
However, if you are rolling your own solution you can eliminate "this" all together if you chose. Douglas Crockford has forsaken "this" youtube.com/watch?v=PSGEjv3Tqo0#t=.... Another opinion can be found here whatsroyupto.blogspot.com/2015/05/.... I believe this technique is called the "Revealing Module Pattern" addyosmani.com/resources/essential...
I do the same, but I wouldn't necessarily say it's bad to use 'this' if you understand how it works well enough. I just find it easier to avoid it than to work out whether I've got it right.
In javascript, there are no absolutes. Your friend is wrong if they believe a single pattern will always be correct. That being said, some guiding principles can be helpful:
thisis valuable when you're working with a stateful object. You can ask yourself: is your object an instance of a "superclass", in that other instances of this object may exist and have different states? it's very likely thatthisis the right tool for the job. In fact, as of es6 the module pattern your friend uses should most likely be refactored to aclass.thiscould be considered dangerous when working with raw objects. If you find yourself using.binda lot, or if you're callingthisfrom inside a method of a non class-like object (e.g. you would never make more than one of the object/function), consider taking a more functional approach. With new Promises and arrow functions, functional javascript has become a lot more fun and readable.This argument IMO is generally a hold-over from when javascript didn't have classes, so you had the option of either constructing using the module pattern like your friend, or using a function constructor and appending methods to the function's prototype. Nowadays, we don't have to argue because we have the
classkeyword.Is
thisa minefield of possible mistakes in javascript? Absolutely not. It's part of the language, and gives us important OOP abilities. You should use it when appropriate!Bad? Bad is not use OOP
It is only when
call,bindandapplyare used for the wrong reasons - or excessively - thatthisstarts to get unpredictable. In my opinionthisis the exact thing that makes Javascript as powerful as it is.thisalways points to the context of the call to the function within which the keyword is used.Arrow functions do what they do because the above statement does not apply to them. Instead, they inherit their
thisvalue from their declaration context.That's all there is to it. It is never arbitrary, nor should it be difficult to determine, where
thispoints to. I think it's just a matter of awareness of the fact that you'll have to look for its value at the preceding call stack, instead of it's lexical scope.I'm generally avoiding the use of this in my code, but most of my code has been AngularJS, and we're very rarely using the object prototype in the first place. Rather than mix-in functions and inheritance, we're using factories and injecting them as dependencies into factories and controllers that depend upon them.
I do kind of have a pet peeve against
const self = this;and have been removing it where I can. I feel like it's a symptom of Java developers that really really want to build a class.That being said, I do sometimes wonder if I'm missing some cool use cases for this.
I've been used to its usage. If he doesn't like it, he can do what he likes. But there are well defined rules for this. He just needs to research and understand it. Don't just hate it because it doesn't make sense to you. Arrow functions and the traditional functions use this differently. It's actually pretty elegant. In my opinion.
I consider Javascript to be an experiment in which Brendan Eich tried a few new ideas, one of which is the behaviour of
this. And unfortunately, it's one of the ideas that didn't work out so well. While the simplicity and flexibility of Javascript's object system is intriguing, and maybethisis a necessary part to make it work, as a programmer on a day to day basis the behaviour ofthisintroduces more stumbling blocks than it adds benefits through flexibility.Put another way, I've had to add more "superfluous"
bind()calls to keep the context on a callback than I used the flexible re-binding mechanism to do something useful I couldn't have otherwise.These kinds of things are only discoverable through longterm use, which Javascript didn't have the time to go through before being released into the wild, and now can't be fixed because backwards compatibility. But that's no reason to throw out the baby with the bathwater; just be aware of it.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.