From: Gabor Krizsanits [mailto:gkrizsan...@mozilla.com] 

> Isn't there a chance to consider our use-case in ES6 spec. then?

I kind of feel like I and others dropped the ball on this one. Until this 
thread I didn't realize how important the dual-stage allocation + 
initialization was, for upgrading in particular. So, we happily helped redesign 
away from the old ES6 dual-stage @@create design to a new ES6 coupled design, 
over the last few weeks.

The @@create design met with heavy implementer resistance from V8, for IMO 
valid reasons. But I think in the rush to fix it we forgot part of why it was 
done in the first place :(

> Yes, and it seems to me that we are trying to hack around the fact that ES6 
> classes are not compatible with what we are trying to do.
> ...
> And if there is no official way to do it people will start to try and hack 
> their way through in 1000 horrible ways...

The interesting thing is, ES5 classes also have the coupled allocation + 
initialization. So, the recent coupled ES6 class design is seen as a natural 
extension that fits well with ES5, while being more flexible and allowing 
subclassable built-ins.

One of the benefits of the new coupled ES6 class design over the coupled ES5 
design is that it exposes enough hooks so that you can, indeed, do such hacks. 
They might not even be so horrible.

For example, if you can just guarantee that everyone uses the constructor only 
for allocation, and puts their initialization code into a initialize() method 
that they call as the last line of their constructor, you can get an 
author-code version of the decoupled @@create design. You could even consider 
calling that initialize() method, say, createdCallback().

Viewed from this perspective, the real benefit of the old ES6 @@create design 
was that it standardized on exactly how that pattern would work: it would 
always be `new C(..args) <=> C.call(C[Symbol.create](), ...args)`. These days, 
if we were to invent our own pattern, so that e.g. `new C(...args) <=> 
C.prototype.createdCallback.call(new C(...args))`, this would only work for 
constructors whose definition we control, instead of all constructors ever. 
This is what leads to the idea (present in the current custom elements spec) of 
`document.registerElement` generating the constructor and ignoring any 
constructor that is passed in.

Reply via email to