Let’s start by writing the classic
In practice, that is mainly syntax sugar for functions:
with “unnecessary complexity.” This complexity applies to the class and all its
new operator, static and private fields, etc.). The
problem with said complexity is that it has no real benefit compared to just
Instead of thinking about everything as a “class,” we should think about it as “data” and “calculations.” This way, we can write the previous example like this:
The main difference between this approach and the class-based is that this one avoids mutations, but besides that, we have a few advantages over “classes”:
- We don’t have to think about
this, because we don’t use it at all.
- We don’t need to use
new, so we can use it anywhere a function can be used, for example, callbacks.
- This approach discourages mutations, which makes our DX far better (predictable data, easier testing and debugging, etc.).
Some common arguments in favor of classes are:
“Classes help with code organization.”
One other thing that helps with code organization are modules. Instead of having a gigantic class with lots of methods, we can simply have a folder with files, each with a small function that we can use independently or group with all the others. So we get the same benefits of a class minus the limitations.
“Classes are more readable.”
Readability has nothing to do with classes and is more with proper naming and
new Shape() and
createShape() are pretty much the same. The
main difference is that when we use the functional approach, the function can be
passed directly as a callback, while the class needs to be put inside a function
new or needs to have static methods.
“Classes are a better abstraction mechanism.”
“Without classes we loose identity.”
For starters, code that depends on
instanceof to work is not good. Functions
should work with any object that has the expected properties. Still, if we want
instanceof, we can simply use
Symbol.hasInstance property, no need for classes.
“Classes are required for OOP.”
This is a widespread misconception. OOP is just a paradigm, and classes aren’t part of it. According to Alan Kay, the “father of OOP”:
“OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.” source
So we only need:
- Dynamic binding.
No mention of classes, and no need for them either. We get all that with functions, closures, and the module system.
Now think about it for a solid minute: Do we need classes, or are we just used to them? Before working as a Web developer, I was a fan of C++, so naturally, I loved classes, but as time passed, I realized that every problem I solved with a class had a cleaner and more straightforward solution just using functions.
We should look at our code in the places we used classes, and then think about how we’ll do that using functions instead. But, of course, the functional approach is always better.