I’m saying the following as someone who does not think that classes are perfect 
(I dislike that they look so different from what they are internally translated 
to), but they will “just work” for most people and they are 
backwards-compatible with much current code.

> Make class inheritance compositional similar to the way stamps are composed. 
> <http://chimera.labs.oreilly.com/books/1234000000262/ch03.html#prototypal_inheritance_with_stamps>
>  In other words, change the behavior of `extend`, or deprecate `extend` and 
> replace it with something like a `compose` keyword that can compose any 
> number of classes.
Traits (or mixins) are coming! A class will be the location where you assemble 
(any number of) traits. IMO, it’s better to have a different construct for this 
than to force classes to serve this use case. In my view, this is your most 
important point and traits are the answer.


> Deprecate `new`. `new` violates both the substitution principle and the open 
> / closed principle. The `new` keyword is 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. 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. If you can’t count on the function to behave the same 
> way for all callers, you can’t predict what the software will do. That’s bad.
> Make sure that `class` obeys the substitution principle when you switch from 
> a class to a factory and vise verse. This is an important point, because 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. Additionally, if callers are counting on the behavior of a factory, and 
> you switch the implementation to a class, that’s similarly problematic, 
> though as it stands, there’s no good reason to switch from a factory to a 
> class.
You can easily return an instance of a subclass or any other object from a 
class constructor. Engines can an will optimize this so that there won’t be any 
difference between a factory function and a class in this regard. In other 
words: you can make the changes you are describing.

> 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.

This assumes that you want to go back and forth between classes and factory 
functions. If you don’t then `this` is not an issue.

> I know I've raised all these issues on es-discuss before and basically been 
> told to go suck an egg, but we all want the same thing -- a better JavaScript 
> for everybody.

I agree. Classes do have drawbacks, but they also have advantages: static 
analyzability, backwards compatibility, the ability to subclass built-ins. I 
can clearly feel your passion, but you are not being completely fair w.r.t. 
their pros and cons.

After traits (in ES7?), I don’t see anything *major* missing from your wish 
list. Things won’t be *exactly* like you want them, but you’ll be able to do 
everything you want to.

-- 
Dr. Axel Rauschmayer
[email protected]
rauschma.de



_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to