How to Fix the ES6 `class` keyword

Nothing is perfect in the first version, but that doesn’t mean it’s hopeless. Maybe we can fix `class` in ES7

Eric Elliott
Mar 3, 2015 · 6 min read

Class is a virus

Image for post
Image for post

Why should we bother?

Why don’t we just create a lint rule and move on?

How to Fix `class`

Make class inheritance compositional

Similar to the way stamps are composed. In other words, change the behavior of `extends`, or deprecate `extends` and replace it with something like a `compose` keyword that can compose any number of classes.

Deprecate `new`

The `new` keyword violates both the substitution principle and the open / closed principle. It’s also destructive because it adds zero value to the language, and it couples all callers to the details of object instantiation.

Make sure that `class` obeys the substitution principle

It’s vital that `class` obeys the substitution principle when you switch from a class to a factory. This is an important point. If callers are counting on any behavior or property of a class and you decide to change the implementation to a factory, you’ve just broken the calling code. I’m not aware of any good reason to switch from a factory to a class.

Deprecate super

Super by definition tightly couples child classes to the parent class, which means any change in the parent class could cause unknowable rippling changes that can break anything that inherits from the parent class.

Catalog of substitution breaks

The problem of substitution is quite serious, and needs to be fixed.

  • The behavior of `this`. It always refers to the new instance in a class constructor. In a factory function, `this` is dynamic, and follows a completely different set of rules. Possible solution: deprecate `this` and instead refer to the class or function by name. A major drawback of this solution is that it would break `.call()`, `.apply()` and `.bind()`, unless we also change their behavior to override the function name reference. I don’t like these solutions. Feel free to chime in with better options.
  • `instanceof`— IMO, `instanceof` is broken anyway because it doesn’t do what the name describes, and from a user’s perspective, it flat out lies when you try to use it across execution contexts, or when the constructor prototype property changes. Possible solution: deprecate `instanceof`.
  • `super` — `super` obviously can’t work for factory functions because inheritance works in a fundamentally different way with factories (the returned instance can be literally anything), and all users should adhere to the public API. Possible solution: deprecate `super`, and good riddance.

JavaScript Scene

JavaScript, software leadership, software development, and…

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store