On Aug 7, 2013, at 1:22 PM, Domenic Denicola wrote:
> From: Allen Wirfs-Brock [[email protected]]
>
>> Which of these questions are still unanswered by the above doc?
>
> Wow, it was a good document; I'm sad I forgot about it.
>
> I think what's still missing would be some guidance, on when it's needed in
> designing platform classes or user classes,
First, this is the default way that the new operator works in ES6. A @@create
method is always involved. Your real question is: When do I need to over-ride
the default implementation of @@create that functions inherit from
Function.prototype
The answer is: Anytime you want newing a constructor function to return an
exotic object, or if you need to brand its instances, associate private state,
or otherwise manipulate the instance before initialization them.
A constructor that returns a proxy is probably the most common example of the
exotic object use case:
class MyExotic {
static [@@create] () {return new Proxy({ }, myHandler)}
constructor (...args) {
//initialize this value using args
}
}
let branded = new WeakSet;
class BrandedMyMe {
static [@@create] () {
let obj = super(); //call the default @@create
branded.add(obj);
return obj
}
constructor (...args) {
if (!branded.has(this)) throw new TypeError();
//initialize this value using args
}
}
class FixedFields {
static [@@create] () {
let obj = super(); //call the default @@create
Object.defineProperty(obj, 'x', {value: 0, writable: true,
configurable: false});
Object.defineProperty(obj, 'y', {value: 0, writable: true,
configurable: false});
return obj
}
constructor (x,y) {
this.x = x;
this.y = y;
}
}
> and why it was used for the new built-ins. (I think this ties
> in to your caution over in public-script-coord to not use that pattern much.)
It's use by built-ins so that the creation of appropriate kinds of exotic
objects, branding, and inclusion of private state slots may be inherited by
subclasses while still allowing the actual constructor initialization to be
over-ridden by the subclass.
The caution is really about avoiding excessive or unnecessary branding.
> Also, what would the practical consequences of moving everything into
> @@create be, ignoring the constructor entirely?
constructor arguments are not passed to @@create. The role of @@create is to
physically allocate the right kind of object based upon the internal design of
the class. The role of the constructor is to initialize the newly allocated
instances based upon the argument pattern passed to the constructor. When
subclassing you are likely to need to independently inherit or over-ride each
capability.
>
> One point I was confused on, that re-reading helped me understand, is that
> @@create actually creates the object instances; it does not manipulate
> passed-in instances. Thus, getting ahold of e.g. `Date[@@create]` or
> `HTMLElement[@@create]` would not allow you to do anything special; you could
> not e.g. turn a normal object into a `Date`. The most you could do is create
> an "uninitialized" object, and what that means exactly depends it seems on
> how much stuff you've shifted into @@create vs. the constructor.
exactly, the rough equivalence to remember is:
new Foo(...args) does the same thing as : Foo.apply(Foo[@@create](), args)
Allen
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss