CalvinTorra
Javascript Classes are Harmful
DIY-PHD

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 factory function because you can’t use this at all in the factory.
  • If you’re not running strict mode and a caller forgets new on a constructor, anything you assign to this 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