[[Construct]] respecification (was: Re: (Weak){Set|Map} subclassing)

Herby Vojčík herby at mailbox.sk
Sat Dec 1 06:29:01 PST 2012



Allen Wirfs-Brock wrote:
>
> On Nov 30, 2012, at 2:20 PM, Jason Orendorff wrote:
>
> The ordinary [[Construct]] internal method (which is what the new
> operator actually uses) when invoked upon a constructor function
> performs two steps. It first instantiates a new object instances (and
> sets its [[Prototype]] internal property). It then calls the constructor
> function using the new object as the this value so that the constructor
> can perform initialization.
>
> In the past on this list we have discussed the utility of being able to
> separately over-ride the [[Construct]] and [[Call]] behavior of a
> function (and Proxies enable this). What Jason is proposing is a
> variation of this. Instead of exposing a @@method that completely
> replaces [[Construct]] he is proposing a method that replaces the
> allocation step of [[Construct]]. Such a method, in addition to
> performing actual allocation, could also perform any allocation time
> initialization that should be separate from the constructor
> functionality. This permits the constructor function to be super invoked
> without doing allocation-time initialization upon the subclass instance.
>
> Overall, I like this approach. However, I don't think @@create belongs
> on the prototype object. This make the @@create functionality for a
> particular kind of object available to anyone who gets their hands on an
> instance object of the class. This smells like a capability leak.
>
> Instead, I would make @@create a property of the actual constructor
> function and I would place the default @@create on Function.prototype,
> which all functions inherit from.
>
> So roughly speaking, Foo.[[Constructor]](...args) would be defined as:
> 1) Let creator be Foo.[[Get]](@@create)
> 2 ) Let newObj be creator.call(foo). //Foo is passed as the this value
> to @@create
> 3) Let ctorResult be Foo.[[call]](newObj,args)
> 4) If Type(ctorResult) is Object, return ctorResult
> 5) else return newObj

I have just thought about this, and came to similar conclusion, but not 
using @@create, but by splitting [[Construct]] into [[Alloc]] and 
[[Init]]. My reasoning was more about speccing that [[Init]] is used 
instead of [[Call]] in new as well as in super(...). So I don't care if 
[[Alloc]] is [[Alloc]] or @@create.

But I did not know whether there is will to respecify [[Construct]]. If 
there is, would it be reasonable to define [[Call]] on functions as well 
as [[Init]] on constructor functions, as invoke it instead of [[Call]] 
in [[Construct]] (and also super(...), but there the [[Call]] is buried 
deeper in some abstract operation)? The default [[Init]] is to delegate 
to [[Call]], but is potentially different.

===============

As a _second_ step / food for thought, not a part of previous proposal, 
so please take them separately, thanks, [[Construct]] could be 
refactored from internal operation ([[...]]) into abstract spec 
operation, and constructor could be tested by presence of [[Init]].

> The definition of the Function.prototype.@@create would be loosely
>
> function() {
> return Object.create(this.prototype);
> }
>
> Allen

Herby


More information about the es-discuss mailing list