Javascript Classes are harmful
Calvin Torra
Posted on June 15, 2021
A pretty bold statement but apparently a common feeling for seasoned Javascript developers.
Javascript is pretty good at letting you code badly if you don't learn it properly! However, this also lets you pick up Javascript and create things pretty quickly without mastering the language.
This phase of messy discovery of Javascript shouldn't last more than a year before diving into the two important paradigms of programming.
- Prototypal Inheritance
- Functional programming.
The creator of Javascript didn't invent these pillars of programming, but Javascript has exposed the masses to them.
Constructors are all wrong
// constructor function
function Person () {
this.name = 'John',
this.age = 23
}
// create an object
const person = new Person();
If you're creating constructor functions and inheriting from them, you're not taking advantage of Javascripts capabilities.
- Returning an object from a constructor function breaks prototypal links, which means
this
is no longer bound to the new object. - It's less flexible than a
real factory function because you can't use
this
. - If you're not running strict mode and a caller forgets
new
on a constructor, anything you assign tothis
moves into the global namespace --- which is baaaad.
Javascript doesn't need constructor functions because any function can return a new object.
Along with object literals
const dog = {
name: 'Naya',
sex: 'female',
age: 2,
breed: 'Rottweiler mix'
};
and by using Object.create()
const person = {
isHuman: false,
printIntroduction: function() {
console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
}
};
const me = Object.create(person);
me.name = 'Matthew'; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten
me.printIntroduction();
// expected output: "My name is Matthew. Am I human? true"
and dynamic object extension
const dynamic1 = "Marks";
const dynamic2 = "Age";
const user = {
Name : "GeeksForGeeks",
[dynamic1] : "57",
[dynamic2] : "42"
};
we apparently have everything we need.
What Are Factory Functions?
function createJelly() {
return {
type: 'jelly',
colour: 'red'
scoops: 3
};
}
Factory functions in Javascript are constructor functions without
- The
new
requirement - Global pollution problems
Classical Inheritance
Classical Inheritance generally only lets you inherit from a single ancestor which puts you in awkward positions later.
Developers generally find that every OO design is eventually wrong.
According to Elliot, child and parent class bonds are as tight as they come, which is the opposite of modular and reusable code.
You can end up having to go back through your codebase reconfiguring what inherits from what, but it's all too tightly couple to properly refactor.
As the application grows, the problem compounds and the mess of classes becomes more brittle ensuring that when a bug pops up, you don't fix it in one place, you fix it everywhere!
Classes are harmful
It's a bold statement to read but Elliot stresses the amount of time wasted in larger organisations due to software rewrites and the problem of duplication by necessity.
Larger organisations have the runway to fiddle around for a few additional months past due dates, but startups don't have that privilege.
ES6 actually made this problem worse by expanding on the class patterns in the newer documentation, 1000's of blog posts and books all push the use of classes.
Cleaner Code
When you remove constructors and classical inheritance from Javascript, it:
- Becomes easier to read and write
- Becomes more flexible
- Becomes more expressive
I know it’s popular to be open-minded about language features, but there is a right way and a wrong way.
Choose the right way.
~ Eric Elliott
My cliff notes on a piece by Eric Elliott
Posted on June 15, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.