I am not going to talk about why OOP is fading away in general, but you can check out this great article for more info.
SportsCar that inherits
Car. Both of them have
model properties and
start method, but
SportsCar also has the
turbocharged property and overrides the
As you probably guessed, the
Car (line 2) and
SportsCar (line 18) functions are constructor functions. The properties are defined using
this keyword and the objects themselves are created with
new. If you are not familiar with
prototype, this is a special property that every JS object has to delegate common behavior. For example, the prototype for array objects has the functions you probably know well:
find, etc. The prototype for strings has functions
After the Car object is created on line 33, you can access its properties and methods. The call to start on line 34 results in the following actions:
- The JS engine asks the
carobject for a value with the key
- The object responds that it has no such value
- The JS engine asks the
car.prototypeobject for a value with the key
startfunction, that the JS engine executes immediately.
Accessing the make and model properties are performed similarly, except they are defined on the car object directly, instead of the prototype.
Inheritance is a bit trickier. It is handled on lines 24–25. The most important function here is the
Object.create function. It accepts an object and returns a brand new one, with its prototype set to whatever was passed as an argument. Now, if the JS engine does not find a value on the
sportsCar object or
sportsCar.prototype, it will consult
sportsCar.prototype.prototype which is the prototype of the
ES6 Class keyword
With the release of ES6 in 2015, the long-awaited
Ok, this is all good, but how does the
class keyword work then? Glad you asked. Do you remember the
SportsCar example earlier? Well, the class keyword is simply syntactic sugar on top of that. In other words, class produces conceptually the same code and serves only aesthetic and readability purposes. As I promised earlier, here is an example of these same classes in ES6:
These examples are identical and produce the same result. What is interesting, they produce (almost) the same code under the hood. I will not write it out here, but if you are curious, head out to the online Babel transpiler and have a look at the output.
Now you should have an understanding of what classes in JS are and how they work. Now, with all this knowledge, I can explain why using classes in JS is a bad idea.
- Binding issues. As class constructor functions deal closely with
thiskeyword, it can introduce potential binding issues, especially if you try to pass your class method as a callback to an external routine (hello, React devs 👋)
- Performance issues. Because of classes’ implementation, they are notoriously difficult to optimize at runtime. While we enjoy performant machines at the moment, the fact that Moore’s law is fading away can change all that.
- Private variables. One of the great advantages and the main reasons for classes in the first place, private variables, is just non-existent in JS.
- Strict hierarchies. Classes introduce a straight top-to-bottom order and make changes harder to implement, which is unacceptable in most JS applications.
- Because the React team tells you not to. While they did not explicitly deprecate the class-based components yet, they are likely to in the near future.
All of these issues can be mitigated with JS objects and prototype delegation. JS offers so much more that classes can ever do, yet most developers are blind to it. If you want to truly master JS, you need to embrace its philosophy and move away from dogmatic class-based thinking.