this post was submitted on 30 Jun 2023
25 points (93.1% liked)

Programming

17484 readers
128 users here now

Welcome to the main community in programming.dev! Feel free to post anything relating to programming here!

Cross posting is strongly encouraged in the instance. If you feel your post or another person's post makes sense in another community cross post into it.

Hope you enjoy the instance!

Rules

Rules

  • Follow the programming.dev instance rules
  • Keep content related to programming in some way
  • If you're posting long videos try to add in some form of tldr for those who don't want to watch videos

Wormhole

Follow the wormhole through a path of communities [email protected]



founded 1 year ago
MODERATORS
 

Hello, everyone ๐Ÿ‘‹. I am a newcomer when it comes to JavaScript. I come from an OOP background (C# and Java). I've recently learned that ES6 has a class keyword that preforms similarly (but not exactly) to common OOP languages. Normally I would be inclined to use this feature in my projects; however, it came to my attention that the usage of class in JavaScript seems to be heavily discussed (mostly in a negative light). My questions to this community are:

  • Should it be used often, sparingly, or be outright avoided?
  • What are its advantages and disadvantages?
  • Are there specific cases where the usage of class excels?

Please share your thoughts.

top 25 comments
sorted by: hot top controversial new old
[โ€“] [email protected] 25 points 1 year ago (2 children)

Whatever you do, I'd recommend using Typescript to give you some type safety with your JS.

[โ€“] DonjonMaister 3 points 1 year ago (1 children)

TypeScript is next on my list. The loose typing of JavaScript drives me a little nuts sometimes ๐Ÿ˜….

[โ€“] [email protected] 1 points 1 year ago* (last edited 1 year ago)

In that case you will love typescript. I'm not sure what other imperative languages have both type inference and structural typing.

[โ€“] [email protected] 2 points 1 year ago (1 children)

I hate the heavy JS env it requires.

Adding jsdoc to standard JS makes the ide provide some type help without TS. I find that to be a good, light alternative.

[โ€“] [email protected] 3 points 1 year ago (1 children)

The IDE support based on JSDoc is typescript (at least it is in all the ones I know about). They're just using TypeScript's JSDoc annotation support under the hood.

I'm not sure what you mean about the "heavy JS env" though, it's just calling tsc in your package.json or whatever build script you're using (or even if none, it's one command).

[โ€“] [email protected] 2 points 1 year ago (1 children)

I don't have nodejs installed. That's the heavy environment it depends on.

[โ€“] [email protected] 3 points 1 year ago

I think you do if your IDE is doing JSDoc-based autocompletion ๐Ÿ˜‰

It's just likely built into your IDE.

[โ€“] [email protected] 9 points 1 year ago (1 children)

The class keyword exists for a reason and it has a perfectly fine use case when you need to make use of creating new objects. I think it may be disliked because people come over from Java assuming you need to define everything as objects/classes when we have modules and other methods of doing the same thing with a little bit less clutter. I recommend reading up on the underlying functionality and how classes and objects work compared to modules.

[โ€“] [email protected] 3 points 1 year ago (2 children)

It's disliked because it uses a "class" keyword but it isn't a class. JavaScript has prototypes, not classes.

[โ€“] object_Object 3 points 1 year ago

I somehow feel like there's an allergy of sort towards classes in general in JavaScript/TypeScript. Many projects I've worked on gravitate towards more functional/plain-old-objects sort of paradigm and it feels like classes are avoided just because they don't feel like idiomatic JS.

[โ€“] DonjonMaister 1 points 1 year ago

Yes. This seems to be one of the common arguments against "classes": they're not exactly classes in the traditional sense, and everything you can do in JavaScript can be done so without touching the class keyword. It's basically syntactic sugar that adds more confusion to the language, or so I heard. I've read this article that explains the flaws behind with this feature: https://www.toptal.com/javascript/es6-class-chaos-keeps-js-developer-up

[โ€“] hairyballs 8 points 1 year ago* (last edited 1 year ago) (1 children)

I don't like/use the class keyword in JS, because I quite like the paradigm with prototypes & stuff, and that keyword tries to make it fit into a totally different paradigm, which doesn't really work IMHO.

With TS, I find it even more useless, because I can use TS as a functional language, with POD, functions and interfaces only. I've written entire projects without ever using and needing this keyword, which is a proof IMHO that it's an unnecessary addition. Not sure how unpopular is my opinion tho ๐Ÿ˜…

BTW, I've developped a few strats to have my own style in TS that I like quite a lot. I can tell more if you're interested.

[โ€“] DonjonMaister 1 points 1 year ago (1 children)

I donโ€™t like/use the class keyword in JS, because I quite like the paradigm with prototypes & stuff, and that keyword tries to make it fit into a totally different paradigm, which doesnโ€™t really work IMHO.

I've read somewhere that Javascript is more of a prototype-oriented language rather than an object-oriented one. Do you agree with this?

BTW, Iโ€™ve developed a few strats to have my own style in TS that I like quite a lot. I can tell more if youโ€™re interested.

Thank you! But maybe not right now; I'm still learning the basics. Have you considered write an article about it? ๐Ÿ˜ฎ

[โ€“] [email protected] 3 points 1 year ago

JavaScript is a prototype-based language. The class keyword uses prototypes.

[โ€“] [email protected] 7 points 1 year ago (1 children)

Probably on the "sparingly" end. As long as you're opting for composition over inheritance, it's probably fine.

[โ€“] DonjonMaister 1 points 1 year ago* (last edited 1 year ago)

As long as youโ€™re opting for composition over inheritance, itโ€™s probably fine.

Totally agree with you there.

Probably on the โ€œsparinglyโ€ end.

I'm on the same train of thought as you. I feel that relying too much on class ignores the better features that JavaScript has to offer. However, I'm sure that its application is useful on the occasion where inheritance IS (but very rarely) necessary.

[โ€“] [email protected] 7 points 1 year ago (1 children)

Not evil, but not the most common or expected way to modularise thing in js/ts, so your colleagues may have to think for a moment before they get used to your code. It's valid solution, though.

I think you should do what's comfortable to you, but also try to adapt to the common language in each of the code ases you will be working on, so that everyone is on the same page.

Typescript is useful, jsdoc type casting is useful, modules are useful.

Good luck in your journey!

[โ€“] DonjonMaister 3 points 1 year ago

I think you should do whatโ€™s comfortable to you

Good advice, but I would like to expand outside of my comfort zone to learn different styles of programming.

but also try to adapt to the common language in each of the code bases you will be working on, so that everyone is on the same page.

Absolutely agree with you there.

Good luck in your journey!

Thank you! โค๏ธ

[โ€“] o11c 6 points 1 year ago

Javascript isn't one of my main language, but using class avoids a few of the footguns Javascript has. You can't forget new, and extends/instanceof are far saner than duck typing.

[โ€“] [email protected] 4 points 1 year ago

Just dont throw away js classes just to use a framework with methods and components that act just like classes. I've seen that enough.

Also sometimes it just makes sense to use classes. Like with UI frameworks.

[โ€“] [email protected] 3 points 1 year ago* (last edited 1 year ago) (1 children)

Classes are very great for their intended use case: the classification of objects.

It's very useful to combine a group of functions that only exist, and can only exist, in conjunction with another object. You also have the ability to take a type and morph it, allowing that one type to have large effects on everything that comes after it. But it has to be intentional. For example, a Button can be split and become an IconButton, or a ToggleButton, etc. It is a double-edged sword, since you can over complicate things when you don't need inheritance.

Many people make the mistake of throwing functions everywhere, but don't see the chain they create. For example: createFoo() will create an object. Then they'll make another function, or a set of functions, that can only work the result of that function. You essentially made a broken apart class. I saw this recently in lit. Their render function returns TemplateResult. Then they have a bunch of functions that only accept TemplateResult as input. That can be rebuilt as a class and have those functions part of the class. Breaking them up instead of using a class isn't necessary. It becomes extra weight to lug that result around instead of having the functions bound to it with this.

There is a good solid excuse for this practice, but it's not a logical one, but an unfortunate consequence of our build tools. Tree-shaking loose functions is much easily done than a class. Because class functions can be invoked by name, it becomes nearly impossible to tree-shake.

People also, sometimes, confuse declarative syntax with functional programming. You can take a class, and use it declaratively, if you build out some helper functions. For example, take a look at [https://github.com/clshortfuse/materialdesignweb/blob/ec892c6f646ea7155edd8f7579389b27d02aa2fb/components/Button.js](this code). It's still a class, that allows extensions, inheritance, function grouping, and construction, but you can manipulate it via a declarative syntax.

That's one of the reasons classes in JavaScript get a bad rap. It's structure is somewhat sporadic and can be hard to follow. But that's a syntax issue, not a construct issue.

That said you should strive to use both functions and classes. If you can simplify your functions to allow mostly any primitive input, that's great. It can be reused many times throughout your code. But if you have certain operations that only work with one type, then don't be afraid to use a class.

[โ€“] DonjonMaister 1 points 1 year ago

This is an excellent take! ๐Ÿ‘

That said you should strive to use both functions and classes. If you can simplify your functions to allow mostly any primitive input, thatโ€™s great. It can be reused many times throughout your code. But if you have certain operations that only work with one type, then donโ€™t be afraid to use a class

This advice looks sound. I'll definitely take it into consideration.

[โ€“] [email protected] 2 points 1 year ago

Classes are great for structuring code.

If you're just starting out, use them. To at least get a feel for them. Even if you later decide against them - in general or selectively.

[โ€“] [email protected] 1 points 1 year ago

You've asked about my favorite soap box! Thank you.

If possible, read this in the voice of that fast ad-copy guy who does medical disclaimers:

Classes suck in Java. Classes suck in C#. Classes suck in JavaScript.

Getting down in the weeds a bit, but bear with me:

Class objects are usually a crutch for keeping needless complexity isolated, but babied like a pet, rather than getting rid of it. A particular sign that this is happening is if there's inheritance in play, or a factory method.

Inheritance is bad and it should feel bad.

Most factory patterns owe more to a developer's massive ego, than to any emergent elegance in the problem space.

Everything good that comes from classes comes from interfaces. Interfaces are great, and they can do everything that classes can, but in a procedural way.

This message was brought to you by that weird cult some of us join after we try Haskell for the first time. It's a great cult. We have cookies every other Friday.

[โ€“] [email protected] 1 points 1 year ago* (last edited 1 year ago)

My opinion is you should use it when it's useful, but not when it's unnecessary. Their main use case is when you need to couple the functionality of functions to a shared state, and it's particularly useful when you have multiple interdependent functions that need to be tied to multiple codependent states.

I find it relatively rare when I really need to use a class. Between first class functions and closures and modules and other features, I find JavaScript has a lot of tools to avoid needing classes. Classes add complexity so I only use them when the complexity they add is less than the complexity of the task they're needed for.

load more comments
view more: next โ€บ