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
TL;DR Because of associated dangers with them (which have caused a lot of real damage to a lot of real projects) we need the ability to disallow `new`, `extends`, `super`, & `instanceof` in our lint rules. ES6 class won’t let us disallow `new` without throwing errors.
It seems inevitable that the `class` keyword in JavaScript is going to catch on, but that’s a problem because it’s fundamentally broken in many ways.
Now that it’s out there and people are using it, it seems like the only logical way forward is to try to make it better for everybody.
In JavaScript, any function can instantiate and return objects. When you do so without a constructor, it’s called a factory function. `class` can’t compete with the power and flexibility of factories — specifically stamps, and object pools are not the only factory use-case.
There is a whole section on object construction in the GoF “Design Patterns” book which exists only to get around the limitations of constructors and classes.
See also: Three Different Kinds of Prototypal OO.
The bottom line: Class doesn’t give you any power that isn’t already supplied by factory functions and the prototypal OO built into the language. All you’re doing when you create a class is opting into a less powerfull, less flexible mechanism and a whole lot of pitfalls and pain.
Class is a virus

Is there any hope that the `class` keyword will ever be useful? Maybe.
Why should we bother?
Why don’t we just create a lint rule and move on?
The `class` keyword is creating a rift in the JavaScript community.
Classes could be useful. What if we want to build abstractions on top of it? What if we want to do more things in the language itself that could benefit with `class` integration (such as built-in traits)?
Shouldn’t the entire JavaScript community benefit from `class`?
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.
There’s already discussion of doing this in ES7, (via traits, probably) and it’s really important that we get it right, and that whatever solution we come up with is call-site compatible with factory functions so that you can easily switch implementations.
As far as I know, even though refactoring to factory functions is fairly common in application development projects, factory substitution transparency is not a high priority on TC-39. Please correct me if I’m wrong, with a link to a reference.
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.
If you start with a class that requires `new` (all classes in ES6) and you later decide you need to use a factory instead of a class, you can’t make the change without refactoring all callers. Take a look at this example gist.
This is especially problematic for shared libraries and public interfaces, because you may not have access to all of the code using the class. You may think it doesn’t do any harm to just call a factory function with the `new` keyword, but the `new` keyword triggers behaviors that change what’s going on when the function is invoked. Certain kinds of factories are difficult to implement with `new`. See the gist for a more in-depth explanation.
Update: According to Brendan Eich, a fix for the `new` issue is being discussed for ES7:
An error caught by a throw is better than one that escapes as a silent-but-deadly (never mind allocation weight) difference in runtime semantics.
In case it helps, the idea mooted for ES7 is that you’d add a “call handler” to the class for when it is invoked without `new`:
