Am I wrong, and should I be listening to my friend? He has much more experience than me.
Am I wrong, and should I be listening to my friend? He has much more experience than me.
At the end of the day, features of languages are just tools, and sometimes they fit the problem you're trying to solve. I think it's also important to decide what tools to use in the context of what experience you and your team already have.
Also, it's hard to have small .js files when you use classes, and I love small files. I think Go made a great design decision to allow functions on structs to be implemented in separate files.
I do use the `class` keyword in my js, but I'm also on a team of C++/Ruby programmers who are forced to write js, so the more I can do to make it more familiar, the better. As you said, it's just a tool. Some people like nails and some people like screws; there are objective advantages to each, but either one will hold a house together.
Immutability and thinking about if a class should really be stateful are the major wins.
I was recently looking over some code that essentially just did transformations, but all the inputs and outputs were member variables, so it took some effort to track what creates what and what depends on what. The members also had empty defaults, so if you mix up the order you call the functions in, the code still appears to work. It wasn't "wrong;" it was hard to follow and error-prone.
It's fine to want to go functionally heavy, but if you're not using classes - which are the foundation of 'types' - then why bother with 'type'script? (Unless you mean to say 'interface'? Which is obviously not 'class' but implies the same usage of OO-founded keywords)
The shape of data is more foundational than classes. An object without a class is a perfectly good way to organize data too, based on its shape.
In that spirit, it's good that you question what experienced people tell you. What about asking your friend to explain why, at a fundamental level, their recommendation is good? "Always use classes and inheritance" as a hard-and-fast rule is not very helpful.
If I’m going to write OOP JS, I generally prefer to use object literals and Object.create. However, I’ve mostly switched to the “Unix philosophy” style that libraries like Ramda promote: lots of sharp tools that are composed to build your programs.
With that said, in real-world projects, the bigger problem is to find the "greatest common divider" - which are the most common skillsets people are familiar with and settle with that. For example, in many full-stack projects, people are more familiar with the backend language which is mostly OO, and it might be a good idea to settle with OO style in the front-end as well. If the functional style is desired in the future, make sure to educate everybody, have a plan, set the direction so everybody can head toward it.
Some Scala projects are struggling with this issue. It results in mixed codebases, where OO guys cannot understand half of the codebase, and the functional guys are angry at OO guys who wouldn't learn, while keep introducing new novelty every month. Operating a team is more than technology, a key part is to keep everybody aligned, and make sure everybody was well taught with the knowledge they need.
If that is really what your friend is saying, I would not listen to him. The world (including the world of programming) is bigger than "always use / do X".
I certainly am not opposed to using classes. If the problem begs to be thought of as a noun, then I will reach for a class to represent it. Especially if we have a collection of nouns, which are related.
But in general I prefer to code in verbs, piping data through a series of functions and then mapping over them at last to produce components, for instance.
Learn to use both and make up your own mind!