How to rewrite classes using closures in JavaScript
21–30 of 58 posts
Re: How to rewrite classes using closures in JavaScript
#22There are private properties in classes class Foo { #ImPrivate = true; #meToo() { if(this.#ImPrivate) cantTouchThis(); } } new Foo().#meToo() === BOOM Also with using closures for "classes" takes up a whole lot more memory because new instances off all the closures are created for each instance of the class.
get name() { return this.#name; }
Half of this article seems to be based on the author’s unawareness of JS class syntax.
Re: How to rewrite classes using closures in JavaScript
#23Amusing bug: console.log(`Average height for dogs is ${AVERAGE_HEIGHT_FT} kg`); Height in kg? ;D
Re: How to rewrite classes using closures in JavaScript
#24And anyway, all of the stated problems either are none or can be solved by using TS.
Re: How to rewrite classes using closures in JavaScript
#25> The this prefix is mandatory for every instance property, which increases code bloat. what does "bloat" mean in this sentence? people use "bloat" liberally nowadays.
Re: How to rewrite classes using closures in JavaScript
#26What is the best and most modern way to write a module where you have public and private functions and data?
If you don’t want to go with classes, not exporting a value or a function from a module is almost the same. The rest can be done with closures.
Re: How to rewrite classes using closures in JavaScript
#27There are private properties in classes class Foo { #ImPrivate = true; #meToo() { if(this.#ImPrivate) cantTouchThis(); } } new Foo().#meToo() === BOOM Also with using closures for "classes" takes up a whole lot more memory because new instances off all the closures are created for each instance of the class.
https://lea.verou.me/blog/2023/04/private-fields-considered-...
Quote:
> Private fields, proxies, pick one, you can’t have both.
Re: How to rewrite classes using closures in JavaScript
#28- no private properties (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...)
- no readonly properties: You can use a getter. Or define the property as non-writable, the syntax isn't nice but in my opinion it's still much nicer than what the article proposes.
Some of the points are just a matter of taste ("this" is awkward)
There's the implementation itself which forces you to use non-idiomatic code for no good reason or benefit (Class.init instead of new, just why? You can absolutely return a constructor function there while preserving everything else)
Doing what the article proposes also destroys the ability to do instanceof checks because the prototype of instances is not set (can be fixed), and inheritance is severely limited if you want to preserve any of the purported benefits. You might say that inheritance is actually not a good thing and so it's a feature, not a bug, but if that's your opinion why are you trying to mimic a class?
Re: How to rewrite classes using closures in JavaScript
#29What is the best and most modern way to write a module where you have public and private functions and data?
classes have the # prefix for private members and TS has the private keyword. If you don’t want to go with classes, not exporting a value or a function from a module is almost the same. The rest can be done with closures.
When looking through npm modules, there still seems to be a variety of approaches.
Re: How to rewrite classes using closures in JavaScript
#30What is the best and most modern way to write a module where you have public and private functions and data?
If you want replicate more class-like behavior (but without actual class/inheritance information):
- Some type of exported constructor function
- The function instantiates an instance of data internally that is possibly mutable (let vs const)
- That function returns an object/interface of functions that have access to that data by virtue of it being defined in a higher but accessible function scope
- All other private functions are simply not exported
Or you might mean singleton data:
- let or const data at the file/module scope level
- export functions to operate on the data
- Don't export functions you want to be private
The first is sort of reinventing a class instance, but if you are anti-inheritance for the most part (likely a good idea), then you can use a "kind" or "type" property on the returned constructed plain object if needed (TypeScript generics make this quite ergonomic to represent as well). So, you don't really need classes, but they have their uses and have familiar and comfortable syntax to programmers from other languages. You can use either and they are both accepted as idiomatic.
I usually still allow classes in codebases that I have some control over, but add a custom ESLint rule to ban extension unless with an ignore comment. This sort of encourages you to compose more like the functional/data approach, but allows you to still use instanceof since it's an actual class. It also means you're not creating a copy of all the method functions if you don't need to between instances.
There is a caveat that there is a class syntax:
method = () => {}
That auto-binds the method to this, creating that method copy for all. In this case you're encroaching on the plain object behaviour, again with a more familiar syntax.
So, I guess it's more messy than I thought reflecting on it. But you have some choices depending on what properties you'd like to encourage in your codebase.