10 ms·
IMO classes are almost pointless without private fields; hiding state (in the handful of cases where that's really actually what you want) is one of their main
by brundolf 5y ago
IMO classes are almost pointless without private fields; hiding state (in the handful of cases where that's really actually what you want) is one of their main legitimate uses
But using static members in a language with module-level constants, functions, etc. just seems incredibly silly to me. And then expanding on that feature with exotic new syntaxes like this feels regressive.
- jancsika 5y agoYes! In Javascript I write a closure that returns an object full of methods. If I want private state I put the variables in that closure. Nothing bad has happened to me yet. :)
- brundolf 5y agoI would argue that that method (no pun intended) is less clear about intent and harder to read There are lots of things like this where the OOP version and the FP version are technically interchangeable in terms of capability, but not in terms of ergonomics or readability. A beautiful thing about working in a multi-paradigm language like JS is that you can reach across the aisle for the best tool for any given job. You can use classes to hide state, plain functions instead of statics, lambdas instead of anonymous classes, etc.
- hajile 5y agoI don't get the intent argument. Closures are private by default while JS classes are public by default. If anything, closures have a more desirable default. The issue is that private variables cause a ton of implementation complexity. The add more overhead when thinking about classes too. In the end, they don't add very much of value except allowing Java or C# programmers to feel more comfortable. Meanwhile, it's giving them a giant footgun in the form of class syntax that looks like what they know, but operates on completely different underlying principles. JS continues to be the only language that people commonly use without having actually bothered to learn properly.
- brundolf 5y agoThere's no need to be rude. > I don't get the intent argument. Classes, from day one, have always been about encapsulating state behind a set of methods (or "passed messages" if you want to go all the way back). If I define a class in my JS codebase, it gives strong signals to others about what my intent was with this code, how it works[0], and how it should be used. A newcomer who encounters the closure method, on the other hand, has to mentally reverse-engineer how it works and what its goal is if they haven't seen that pattern before, because closures are much more general than classes and because returning a closure is less common and its behavior less obvious compared to other ways closures tend to be used in JS. > The issue is that private variables cause a ton of implementation complexity. I think a case could be made that private members should have been left up to type systems like TypeScript (which I believe virtually every JS codebase should be using at this point anyway) instead of implemented in the JS engine at runtime. At this point I see plain JS as a bit of an "all bets are off" language, so maybe it wasn't worth trying to plug one hole given how many others still remain. But on the other hand, like I've said, I think classes are nearly useless without private members, and they do exist in JS already so there's an argument to be made that we should at least make them useful. > In the end, they don't add very much of value except allowing Java or C# programmers to feel more comfortable. It's a tired trope that every single feature associated with Java or C# is "just there to make Java and C# programmers feel comfortable" and is therefore invalid and useless. > Meanwhile, it's giving them a giant footgun in the form of class syntax that looks like what they know, but operates on completely different underlying principles. The only footgun I've encountered with the ES class syntax is when passing classInstance.someMethod as a value (`this` is normally unbound because the method exists on the prototype instead of the instance). But a) this is not something (to my knowledge) that you can even do in those other languages, so the proverbial "Java and C# programmers" should have no preexisting expectations around how it behaves, and b) the solution is just "always use arrow syntax for methods if you want this to work the way JS would have you expect". I've worked with many junior programmers who have no problem doing the latter, even when they don't yet have a full understanding of why it's needed. [0] How it works at the application logic level; the underlying way that classes work is rarely an issue that comes up.
- 5y ago
- LouisSayers 5y agoAh yes, the good parts :) I've found understanding exactly how JS works to become more confusing with class structures. It feels like you need a PHD in JS to have a good grip on how it all works under the covers. Using Crockfords closure strategy for me was quite straightforward and simple, and I've enjoyed doing: const MyClass = {}; MyClass.new = () => {}; const instance = MyClass.new(); Which leaves all the "this." ugliness behind and provides a ruby-like instantiation.