Allen Wirfs-Brock (2014-06-13T17:51:18.000Z)
domenic at domenicdenicola.com (2014-06-20T19:40:25.575Z)
On Jun 13, 2014, at 7:51 AM, Boris Zbarsky wrote: > The basic question is how that affects what WebIDL needs here is how it should play with subclassing. > > If we don't care about subclassing WebIDL objects, there is no issue: WebIDL can just override [[Call]] as it does right now and we move on with life. Note that some implementations at the moment override [[Construct]], not [[Call]] and just throw from [[Call]], so as to preclude web pages from relying on the current spec's [[Call]] behavior, since that would presumably interact badly with trying to introduce subclassing. This "we" definitely cares about subclassing WebIDL objects and the ES6 object creation protocol was design with that in mind. > If we do care about subclassing, then presumably the "construct the right sort of object" and "initialize it" actions need to be somewhat decoupled for these objects. It seems to me that both Allen's current spec and Jason's proposal accomplish that, right? Right, Jason's proposal introduces an additional degree of variability that my proposal (assuming that [[Construct goes away) doesn't directly provide. It kind of comes down to whether that extra flexibility is actually needed. > In Jason's proposal it would look like this, if I understand it right: > > ```js > subclass[Symbol.new] = function(...args) { > // Modify args as desired. > var obj = superclass[Symbol.new](...args); > // Modify obj as desired. > return obj; > } > ``` I don't think so. Unless, I misunderstand I don't think Jason is proposing eliminating @@create. So, in most cases including, I believe, the WebIDL use cases a constructor would simply use the default @@new that would be inherited from Function.prototype. It's definition would be something like: ```js Function.prototype[Symbol.new] = function (...args) { let newObj = this[Symbol.create](); if (! IsObject(newObj) { //default handling for ill-behaved or missing @@create } let ctorResult = this(...args); if (IsObject(ctorResult) return ctorResult; //ES<6 compatibility else return newObj; } ``` Note that this preserves the separation between object allocation and object initialization we need to make subclassing work correctly. > which is pretty similar to how this would be done without classes: > > ```js > function subclass(...args) { > // Assume that we're being invoked via new. > // Modify args as desired. > var obj = new superclass(...args); > // Modify obj as desired. > return obj; > } > ``` Except that the above doesn't give you true subclassing. The object you return is an instance of the superclass and not of the subclass. The key thing that @@create is doing is separating determining the physical characteristics of an object (making it exotic, branding it, using a custom C struct as its representation, etc.) from logically initializing it at an appropriate place within some class hierarchy > Is my understanding of the Allen and Jason's proposals correct? I'd like to avoid making any claims of how these interact with WebIDL until I'm sure I'm not missing something important. I think you are missing the key element @@create plays in both proposals. The only real difference, I think, is whether you have to live with the default @@create/constructor protocol or whether you are allowed to tweak with that default.