RE: Custom element design with ES6 classes and Element constructors

From: Gabor Krizsanits [mailto:gkrizsanits@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.

Received on Tuesday, 13 January 2015 17:21:59 UTC